问题遇到的现象和发生背景
深度学习,模型训练遇到的问题
"""
卷积神经网络对MUIST数据集分类
"""
import torch
from torch import nn
import numpy as np
import torch.optim as optim
from matplotlib import pyplot
import torch.nn.functional as F
from sklearn.model_selection import train_test_split
from torch.utils.data import TensorDataset,DataLoader
def read_image(file_path):
"""读取MNIST图片
Args:
file_path (str): 图片文件位置
Returns:
list: 图片列表
"""
with open(file_path,'rb') as f:
file = f.read()
img_num = int.from_bytes(file[4:8],byteorder='big') #图片数量
img_h = int.from_bytes(file[8:12],byteorder='big') #图片h
img_w = int.from_bytes(file[12:16],byteorder='big') #图片w
img_data = []
file = file[16:]
data_len = img_h*img_w
for i in range(img_num):
data = [item/255 for item in file[i*data_len:(i+1)*data_len]]
img_data.append(np.array(data).reshape(img_h,img_w))
return img_data
def read_label(file_path):
with open(file_path,'rb') as f:
file = f.read()
label_num = int.from_bytes(file[4:8],byteorder='big') #label的数量
file = file[8:]
label_data = []
for i in range(label_num):
label_data.append(file[i])
return label_data
train = read_image("data/mnist/train-images-idx3-ubyte/train-images.idx3-ubyte")
label = read_label("data/mnist/train-labels-idx1-ubyte/train-labels.idx1-ubyte")
# pyplot.imshow(train[0].reshape((28,28)),cmap="gray")
# pyplot.show()
print(train[1].shape)
#定义超参数
input_size = 28 #图像总尺寸28*28
num_classes = 10 #标签的种类
num_epochs = 3 #训练的总循环周期
batch_size = 64 #一个批次的大小,64张图片
#划分数据集
train_img,valid_img,train_label,valid_label = train_test_split(train,label,test_size=0.2,shuffle=True)
# train_img,valid_img,train_label,valid_label = map(torch.tensor,(train_img,valid_img,train_label,valid_label))
# print(type(train_img),type(train_label))
train_img = np.array(train_img)
train_label = np.array(train_label)
valid_img = np.array(valid_img)
valid_label = np.array(valid_label)
train_img = torch.from_numpy(train_img)
train_label = torch.from_numpy(train_label)
valid_img = torch.from_numpy(valid_img)
valid_label = torch.from_numpy(valid_label)
#构建batch数据
train_ds = TensorDataset(train_img,train_label)
train_loader = DataLoader(dataset=train_ds,batch_size=batch_size,shuffle=True)
test_dl = TensorDataset(valid_img,valid_label)
test_loader = DataLoader(dataset=test_dl,batch_size=batch_size,shuffle=True)
class MyNet_CNN(nn.Module):
def __init__(self):
super(MyNet_CNN, self).__init__()
self.conv_1 = nn.Sequential( #输入 (1,28,28)
nn.Conv2d(
1, #输入的特征图数(原始图为灰度图一层)
16, #得到16个特征图
kernel_size=5, #卷积核的大小
stride=1, #步长
padding=2 #图片填充层数
), #输出(16,28,28)
nn.ReLU(), #relu层(激活函数)
nn.MaxPool2d(kernel_size=2), #进行池化操作(2*2区域),输出结果为 (16,24,24)
)
self.conv_2 = nn.Sequential( #进入下一个层 输入(16,24,24)
nn.Conv2d(16, 32, kernel_size=5, stride=1,padding=2), #输出(32,14,14)
nn.ReLU(),
nn.MaxPool2d(2),#输出(32,7,7)
)
self.out = nn.Linear(32*7*7,10) #全连接层的得到的结果
"""前向传播"""
def forward(self, x):
x = self.conv_1(x)
x = self.conv_2(x)
x = x.view(x.size(0), -1) #将结果转化为向量
output = self.out(x)
return output
"""准确率作为评估标准"""
def accuracy(predictions,labels):
pred = torch.max(predictions.data,1)[1]
rights = pred.eq(labels.data.view_as(pred)).sum()
return rights,len(labels)
"""训练网络模型"""
#实例化
net = MyNet_CNN()
#s损失函数
criterion = nn.CrossEntropyLoss()
#优化器
optimizer = optim.Adam(net.parameters(),lr=0.001)
#开始训练循环
for epoch in range(num_epochs):
#当前的epoch结果(准确率)保存下来
train_rights = []
for batch_idx,(data,target) in enumerate(test_loader): #针对容器的每一个批次进行循环
net.train()
output =net(data)
loss =criterion(output,target)
optimizer.zero_grad()
loss.backward()
optimizer.step()
right = accuracy(output,target)
train_rights.append(right)
if batch_idx % 100 == 0:
net.eval()
val_rights = []
for (bata,target) in test_loader:
output = net(data)
right =accuracy(output,target)
#准确率计算
train_r = (sum(tup[0] for tup in train_rights),sum(tup[1] for tup in train_rights))
val_r = (sum(tup[0] for tup in val_rights),sum(tup[1] for tup in val_rights))
print('当前epoch: {} [{}/{} ({:.0f}%)]\t损失: {:.6f}\t训练集准确率: {:.2f}%\t测试集正确率: {:.2f}%'.format(
epoch,batch_idx*batch_size,len(train_loader.dataset),
100. * batch_idx / len(train_loader),
loss.data,
100. * train_r[0].numpy() / train_r[1],
100. * val_r[0].numpy() / val_r[1]
))
运行结果及报错内容
RuntimeError Traceback (most recent call last)
Input In [1], in <cell line: 128>()
132 for batch_idx,(data,target) in enumerate(test_loader): #针对容器的每一个批次进行循环
133 net.train()
--> 134 output =net(data)
135 loss =criterion(output,target)
136 optimizer.zero_grad()
File D:\anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
1126 # If we don't have any hooks, we want to skip the rest of the logic in
1127 # this function, and just call forward.
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1129 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130 return forward_call(*input, **kwargs)
1131 # Do not call functions when jit is used
1132 full_backward_hooks, non_full_backward_hooks = [], []
Input In [1], in MyNet_CNN.forward(self, x)
106 def forward(self, x):
--> 107 x = self.conv_1(x)
108 x = self.conv_2(x)
109 x = x.view(x.size(0), -1) #将结果转化为向量
```c
File D:\anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
1126 # If we don't have any hooks, we want to skip the rest of the logic in
1127 # this function, and just call forward.
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1129 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130 return forward_call(*input, **kwargs)
1131 # Do not call functions when jit is used
1132 full_backward_hooks, non_full_backward_hooks = [], []
File D:\anaconda3\lib\site-packages\torch\nn\modules\container.py:139, in Sequential.forward(self, input)
137 def forward(self, input):
138 for module in self:
--> 139 input = module(input)
140 return input
File D:\anaconda3\lib\site-packages\torch\nn\modules\module.py:1130, in Module._call_impl(self, *input, **kwargs)
1126 # If we don't have any hooks, we want to skip the rest of the logic in
1127 # this function, and just call forward.
1128 if not (self._backward_hooks or self._forward_hooks or self._forward_pre_hooks or _global_backward_hooks
1129 or _global_forward_hooks or _global_forward_pre_hooks):
-> 1130 return forward_call(*input, **kwargs)
1131 # Do not call functions when jit is used
1132 full_backward_hooks, non_full_backward_hooks = [], []
File D:\anaconda3\lib\site-packages\torch\nn\modules\conv.py:457, in Conv2d.forward(self, input)
456 def forward(self, input: Tensor) -> Tensor:
--> 457 return self._conv_forward(input, self.weight, self.bias)
File D:\anaconda3\lib\site-packages\torch\nn\modules\conv.py:453, in Conv2d._conv_forward(self, input, weight, bias)
449 if self.padding_mode != 'zeros':
450 return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode),
451 weight, bias, self.stride,
452 _pair(0), self.dilation, self.groups)
--> 453 return F.conv2d(input, weight, bias, self.stride,
454 self.padding, self.dilation, self.groups)
RuntimeError: Given groups=1, weight of size [16, 1, 5, 5], expected input[1, 64, 28, 28] to have 1 channels, but got 64 channels instead
###### 我的解答思路和尝试过的方法
毫无思路,不知道错哪
```typescript