理解CGAN中标签输入的帮助

我正在尝试实现一个CGAN。我明白在卷积生成器和判别器模型中,通过增加代表标签的深度来增加输入的体积。因此,如果你的数据中有10个类别,那么你的生成器和判别器的输入体积都将是基础深度加上10。

然而,我在网上查看了各种实现方式,但似乎找不到他们实际获取标签的地方。CGAN肯定不能是无监督的,因为你需要获取标签来输入。例如,在cifar10中,如果你在训练判别器处理一只青蛙的真实图像,你需要’青蛙’的注释。

这是我正在研究的一段代码:

class CGAN(object):def __init__(self, args):    # parameters    self.epoch = args.epoch    self.batch_size = args.batch_size    self.save_dir = args.save_dir    self.result_dir = args.result_dir    self.dataset = args.dataset    self.log_dir = args.log_dir    self.gpu_mode = args.gpu_mode    self.model_name = args.gan_type    self.input_size = args.input_size    self.z_dim = 62    self.class_num = 10    self.sample_num = self.class_num ** 2    # load dataset    self.data_loader = dataloader(self.dataset, self.input_size, self.batch_size)    data = self.data_loader.__iter__().__next__()[0]    # networks init    self.G = generator(input_dim=self.z_dim, output_dim=data.shape[1], input_size=self.input_size, class_num=self.class_num)    self.D = discriminator(input_dim=data.shape[1], output_dim=1, input_size=self.input_size, class_num=self.class_num)    self.G_optimizer = optim.Adam(self.G.parameters(), lr=args.lrG, betas=(args.beta1, args.beta2))    self.D_optimizer = optim.Adam(self.D.parameters(), lr=args.lrD, betas=(args.beta1, args.beta2))    if self.gpu_mode:        self.G.cuda()        self.D.cuda()        self.BCE_loss = nn.BCELoss().cuda()    else:        self.BCE_loss = nn.BCELoss()    print('---------- Networks architecture -------------')    utils.print_network(self.G)    utils.print_network(self.D)    print('-----------------------------------------------')    # fixed noise & condition    self.sample_z_ = torch.zeros((self.sample_num, self.z_dim))    for i in range(self.class_num):        self.sample_z_[i*self.class_num] = torch.rand(1, self.z_dim)        for j in range(1, self.class_num):            self.sample_z_[i*self.class_num + j] = self.sample_z_[i*self.class_num]    temp = torch.zeros((self.class_num, 1))    for i in range(self.class_num):        temp[i, 0] = i    temp_y = torch.zeros((self.sample_num, 1))    for i in range(self.class_num):        temp_y[i*self.class_num: (i+1)*self.class_num] = temp    self.sample_y_ = torch.zeros((self.sample_num, self.class_num)).scatter_(1, temp_y.type(torch.LongTensor), 1)    if self.gpu_mode:        self.sample_z_, self.sample_y_ = self.sample_z_.cuda(), self.sample_y_.cuda()def train(self):    self.train_hist = {}    self.train_hist['D_loss'] = []    self.train_hist['G_loss'] = []    self.train_hist['per_epoch_time'] = []    self.train_hist['total_time'] = []    self.y_real_, self.y_fake_ = torch.ones(self.batch_size, 1), torch.zeros(self.batch_size, 1)    if self.gpu_mode:        self.y_real_, self.y_fake_ = self.y_real_.cuda(), self.y_fake_.cuda()    self.D.train()    print('training start!!')    start_time = time.time()    for epoch in range(self.epoch):        self.G.train()        epoch_start_time = time.time()        for iter, (x_, y_) in enumerate(self.data_loader):            if iter == self.data_loader.dataset.__len__() // self.batch_size:                break            z_ = torch.rand((self.batch_size, self.z_dim))            y_vec_ = torch.zeros((self.batch_size, self.class_num)).scatter_(1, y_.type(torch.LongTensor).unsqueeze(1), 1)            y_fill_ = y_vec_.unsqueeze(2).unsqueeze(3).expand(self.batch_size, self.class_num, self.input_size, self.input_size)            if self.gpu_mode:                x_, z_, y_vec_, y_fill_ = x_.cuda(), z_.cuda(), y_vec_.cuda(), y_fill_.cuda()            # update D network            self.D_optimizer.zero_grad()            D_real = self.D(x_, y_fill_)            D_real_loss = self.BCE_loss(D_real, self.y_real_)            G_ = self.G(z_, y_vec_)            D_fake = self.D(G_, y_fill_)            D_fake_loss = self.BCE_loss(D_fake, self.y_fake_)            D_loss = D_real_loss + D_fake_loss            self.train_hist['D_loss'].append(D_loss.item())            D_loss.backward()            self.D_optimizer.step()            # update G network            self.G_optimizer.zero_grad()            G_ = self.G(z_, y_vec_)            D_fake = self.D(G_, y_fill_)            G_loss = self.BCE_loss(D_fake, self.y_real_)            self.train_hist['G_loss'].append(G_loss.item())            G_loss.backward()            self.G_optimizer.step()

看起来y_vec_y_fill_是图像的标签,但在y_fill_的实例中,它用于给判别器标记真实图像,等于y_fill_ = y_vec_.unsqueeze(2).unsqueeze(3).expand(self.batch_size, self.class_num, self.input_size, self.input_size)

似乎它没有从数据集中获取任何关于标签的信息?它是如何给判别器提供正确的标签的?

谢谢!


回答:

y_fill_基于y_vec_,而y_vec_基于y_,所以它们是从小批量中读取标签信息的,这是正确的。你可能会对scatter操作感到困惑,基本上代码所做的是将标签转换为独热编码

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注