时间管理菌 2022-08-10 19:07 采纳率: 100%
浏览 76
已结题

关于#深度学习#的问题,如何解决?

问题遇到的现象和发生背景

深度学习,模型训练遇到的问题

"""
卷积神经网络对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


  • 写回答

2条回答 默认 最新

  • SmallAntJ 2022-08-11 03:37
    关注

    这里的错误提示是说第107行self.conv_1(x)的输入x的维度不对,输入x需要是1 channels而不是64 channels。x的维度应该是[64, 1, 28, 28]而不是[64, 28, 28],这里64是batch_size,28是图片大小,还需要一个channel的数目(和nn.Conv2d第一个参数对应)。你写的数据预处理的部分需要改一下。或者最简单的办法是在107行前面加一句对x的预处理:

        def forward(self, x):
            x = torch.unsqueeze(x,1).type(torch.FloatTensor) #增加一个channel的维度同时把tensor的数据类型改为float
            #print(x.size(), x.type())
            x = self.conv_1(x)
            x = self.conv_2(x)
            x = x.view(x.size(0), -1) #将结果转化为向量
            output = self.out(x)
            return output
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 8月20日
  • 已采纳回答 8月12日
  • 创建了问题 8月10日

悬赏问题

  • ¥20 机器学习能否像多层线性模型一样处理嵌套数据
  • ¥20 西门子S7-Graph,S7-300,梯形图
  • ¥50 用易语言http 访问不了网页
  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效