LZT. 2024-03-05 21:31 采纳率: 20%
浏览 30
已结题

Python基于自建图像数据集运行CGAN模型

代码与报错如下该如何解决,数据集是1368*208尺寸的图片,标签共5类。


import matplotlib
matplotlib.use("TkAgg") # 设置交互式后端

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader
import torchvision
from torchvision.datasets import ImageFolder
import torchvision.transforms as transforms

import numpy as np
import matplotlib.pyplot as plt

# 数据预处理
transform = transforms.Compose([
transforms.Resize((1368, 208)),
transforms.ToTensor(),
transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])



# 独热编码,将标签转变成张量形式
def one_hot(x, class_count=10):
x = torch.LongTensor(x) # 将x转换为LongTensor类型
return torch.eye(class_count)[x, :]


# 加载数据集
dataset = ImageFolder(root='G:\project\data\dataset', transform=transform)

# 数据加载器
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)


# 生成器的初始化部分
# PS:1.输出层要用Tanh激活函数 2.使用batchnorm,解决初始化差的问题,帮助梯度传播到每一层,防止生成器包所有的样本都收敛到同一个点
class Generator(nn.Module):
def __init__(self):
super(Generator, self).__init__()
self.linear1 = nn.Linear(100, 128 * 43 * 7)
self.bn1 = nn.BatchNorm1d(128 * 7 * 7)
self.linear2 = nn.Linear(10, 128 * 43 * 7)
self.bn2 = nn.BatchNorm1d(128 * 43 * 7)
# 这里是反卷积,stride=2即让图像放大2倍,padding=2即往里缩小两格。
self.decon1 = nn.ConvTranspose2d(in_channels=256, out_channels=128,
kernel_size=(3, 3),
stride=2,
padding=1,
output_padding=1)
self.bn3 = nn.BatchNorm2d(128)
self.decon2 = nn.ConvTranspose2d(128, 64,
kernel_size=(4, 4),
stride=2,
padding=1,
output_padding=1)
self.bn4 = nn.BatchNorm2d(64)
self.decon3 = nn.ConvTranspose2d(64, 3,
kernel_size=(4, 4),
stride=2,
padding=1,
output_padding=1)

def forward(self, x1, x2):
x1 = F.relu(self.linear1(x1))
x1 = self.bn1(x1)
x1 = x1.view(-1, 128, 43, 7)
x2 = F.relu(self.linear2(x2))
x2 = self.bn2(x2)
x2 = x2.view(-1, 128, 43, 7)
x = torch.cat([x1, x2], dim=1)
x = F.relu(self.decon1(x))
x = self.bn3(x)
x = F.relu(self.decon2(x))
x = self.bn4(x)
x = torch.tanh(self.decon3(x))
return x


# 判别器的初始化部分

class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.linear = nn.Linear(10, 128 * 43 * 7).float()
self.conv1 = nn.Conv1 = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=2)
self.conv2 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3, stride=2)
self.bn = nn.BatchNorm2d(128)
self.fc = nn.Linear(128 * 43 * 7, 1)

def forward(self, x1, x2):
x1 = F.leaky_relu_(self.linear(x1.float()))
x1 = x1.view(-1, 128, 43, 7)
x = torch.cat([x1, x2], dim=1)
x = F.dropout2d(F.leaky_relu_(self.conv1(x))) # nn.LeakyReLU() 更适合作为模型的一部分使用,因为它会返回一个新的张量,而不会修改原始数据
x = F.dropout2d(F.leaky_relu_(self.conv2(x)))
x = self.bn(x)
x = x.view(-1, 128 * 43 * 7)
x = torch.sigmoid(self.fc(x))
return x


# 初始化模型,定义优化器,损失函数
device = 'cuda' if torch.cuda.is_available() else 'cpu'
gen = Generator().to(device)
dis = Discriminator().to(device)
g_optim = torch.optim.Adam(gen.parameters(), lr=0.0001)
d_optim = torch.optim.Adam(dis.parameters(), lr=0.0001) # PS:将判别器的学习率设置小一点可以减小其学习速度,防止一边倒
loss_fun = torch.nn.BCELoss()


# 定义绘图函数

def gen_img_plot(model, label_input, noise_input):
# 将标签转换为独热编码形式
label_onehot = one_hot(label_input, class_count=10).to(device)
# 通过生成器生成图像
gen_img = gen(noise_input, label_onehot)
# 使用判别器评估生成的图像
prediction = np.squeeze(dis(label_onehot, gen_img).cpu().numpy())
# 绘制图像
fig, axes = plt.subplots(nrows=4, ncols=4, figsize=(4, 4))
for i, ax in enumerate(axes.flat):
ax.imshow((prediction[i] + 1) / 2, cmap="gray")
ax.axis("off")
plt.draw() # 强制绘制图形
plt.pause(0.001) # 留出足够的时间显示图像


noise_seed = torch.randn(16, 100, device=device)
label_seed = torch.randint(0, 10, size=(16,))
label_seed_onehot = one_hot(label_seed,class_count=10).to(device)
print(label_seed)

# 训练GAN
G_loss = []
D_loss = []
for epoch in range(10):
g_epoch_loss = 0
d_epoch_loss = 0
count = len(dataloader)
for step, (img, label) in enumerate(dataloader):
img = img.to(device)
label = label.to(device)
size = img.shape[0]
random_seed = torch.randn(size, 100, device=device)
# 优化判别器
d_optim.zero_grad()
# 优化真实图片
real_output = dis(label, img)
real_loss = loss_fun(real_output, torch.ones_like(real_output, device=device))
real_loss.backwar()
gen_img = gen(random_seed, label)
fake_output = dis(label, gen_img.detach())
fake_loss = loss_fun(fake_output, torch.zeros_like(fake_output, device=device))
fake_loss.backward()

d_loss = real_loss + fake_loss
d_optim.step()

# 优化生成器
g_optim.zero_grad()
fake_output = dis(label, gen_img)
g_loss = loss_fun(fake_output, torch.ones_like(fake_output, device=device))
g_loss.backward()
g_optim.step()

with torch.no_grad():
d_epoch_loss += d_loss.item()
g_epoch_loss += g_loss.item()

with torch.no_grad():
d_epoch_loss /= count
g_epoch_loss /= count
D_loss.append(d_epoch_loss)
G_loss.append(g_epoch_loss)
print("Epoch:", epoch)
print(label_seed)
gen_img_plot(gen, label_seed, noise_seed)

plt.plot(D_loss, label="D_loss")
plt.plot(G_loss, label="G_loss")
plt.legend()
plt.show()

报错如下:


Traceback (most recent call last):
  File "G:\project\CGAN1.py", line 151, in <module>
    real_output = dis(label, img)
  File "C:\Users\16043\venv\lib\site-packages\torch\nn\modules\module.py", line 1511, in _wrapped_call_impl
    return self._call_impl(*args, **kwargs)
  File "C:\Users\16043\venv\lib\site-packages\torch\nn\modules\module.py", line 1520, in _call_impl
    return forward_call(*args, **kwargs)
  File "G:\project\CGAN1.py", line 95, in forward
    x = torch.cat([x1, x2], dim=1)
RuntimeError: Sizes of tensors must match except in dimension 1. Expected size 1 but got size 10 for tensor number 1 in the list.

进程已结束,退出代码1
  • 写回答

24条回答 默认 最新

  • 码农阿豪@新空间代码工作室 Java领域优质创作者 2024-03-06 16:23
    关注
    获得1.00元问题酬金
    让阿豪来帮你解答,本回答参考chatgpt3.5编写提供,如果还有疑问可以评论或留言
    该代码存在一个缺失的部分,无法判断需要解决的问题是什么。请提供更完整的代码和问题描述。
    评论

报告相同问题?

问题事件

  • 系统已结题 3月13日
  • 修改了问题 3月5日
  • 创建了问题 3月5日

悬赏问题

  • ¥15 grbl的G92修改MPos的问题。
  • ¥15 vue2中,Ant Design Pro s-table中,使用服务端排序怎么做
  • ¥15 阿里巴巴国际站的商品详细页如何做到图文分离
  • ¥15 根据质因子个数求因式个数
  • ¥15 matlab模糊控制隶属函数设计
  • ¥15 DB2的REPLACE函数报错求解
  • ¥45 C++上传文件到SFTP
  • ¥20 组态王 海康Vision Master
  • ¥15 思科WS-C4503-E核心交机
  • ¥15 批量提取WORD信息到EXCEL