RuntimeError: Expected 4-dimensional input for 4-dimensional weight [32, 1, 5, 5]

2023-05-16

文章目录

  • 1. 问题引入
  • 2. 运行报错
  • 3. 代码
  • 4. 分析原因
  • 5.解决办法
  • 6. 完整代码
  • 7. 参考文献

1. 问题引入

今天在使用pytorch训练一个模型的,数据集的读取是使用pytorch自带的函数来进行读取和预处理的,网络使用的是自定义的CNN,然后在运行的时候出现了如标题所示的这种小错误。

2. 运行报错

如下所示:

RuntimeError: Expected 4-dimensional input for 4-dimensional weight [32, 1, 5, 5], but got 2-dimensional input of size [32, 784] instead

3. 代码

首先是我自己自定义的CNN网络如下所示:

class MNIST_Model(nn.Module):
    def __init__(self, n_in):
        super(MNIST_Model, self).__init__()

        self.conv1 = nn.Sequential(
            nn.Conv2d(in_channels=n_in,
                      out_channels=32,
                      kernel_size=(5, 5),
                      padding=2,
                      stride=1),
        )

        self.maxp1 = nn.MaxPool2d(
                       kernel_size=(2, 2))

        self.conv2 = nn.Sequential(
            nn.Conv2d(in_channels=32,
                      out_channels=64,
                      kernel_size=(5, 5),
                      padding=0,
                      stride=1),
        )

        self.maxp2 = nn.MaxPool2d(kernel_size=(2, 2))
        
        self.fc1 = nn.Sequential(
            nn.Linear(in_features=64 * 5 * 5, out_features=200)  # Mnist
        )

        self.fc2 = nn.Sequential(
            nn.Linear(in_features=200, out_features=10),
            nn.ReLU()
        )


    def forward(self, x):
        x = self.conv1(x)
        x = self.maxp1(x)
        x = self.conv2(x)
        x = self.maxp2(x)
        x = x.contiguous().view(x.size(0), -1)
        x = self.fc1(x)
        x = self.fc2(x)
        return x

然后是在训练模型的代码

#实例化网络,只考虑使用CPU
model = model.MNIST_Model(1)
net = model.to(device)
#定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
#momentum:动量因子有什么用处?
optimizer = optim.SGD(model.parameters(),lr=lr,momentum=momentum)


#开始训练 先定义存储损失函数和准确率的数组
losses = []
acces = []
#测试用
eval_losses = []
eval_acces = []

for epoch in range(nums_epoches):
    #每次训练先清零
    train_loss = 0
    train_acc = 0
    #将模型设置为训练模式
    model.train()
    #动态学习率
    if epoch%5 == 0:
        optimizer.param_groups[0]['lr'] *= 0.1
    for img,label in train_loader:
        #前向传播,将图片数据传入模型中
        # out输出10维,分别是各数字的概率,即每个类别的得分
        out = model(img)
        #这里注意参数out是64*10,label是一维的64
        loss = criterion(out,label)
        #反向传播
        #optimizer.zero_grad()意思是把梯度置零,也就是把loss关于weight的导数变成0
        optimizer.zero_grad()
        loss.backward()
        #这个方法会更新所有的参数,一旦梯度被如backward()之类的函数计算好后,我们就可以调用这个函数
        optimizer.step()
        
        #记录误差 
        train_loss += loss.item()
        
        #计算分类的准确率,找到概率最大的下标
        _,pred = out.max(1)
        num_correct = (pred == label).sum().item()#记录标签正确的个数
        acc = num_correct/img.shape[0]
        train_acc += acc
    losses.append(train_loss/len(train_loader))
    acces.append(train_acc/len(train_loader))
    
    eval_loss = 0
    eval_acc = 0
    model.eval()
    for img,label in test_loader:
        img = img.view(img.size(0),-1)
        
        out = model(img)
        loss = criterion(out,label)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        eval_loss += loss.item()
        
        _,pred = out.max(1)
        num_correct = (pred == label).sum().item()
        acc = num_correct/img.shape[0]
        eval_acc += acc
    eval_losses.append(eval_loss/len(test_loader))
    eval_acces.append(eval_acc/len(test_loader))
    

    print('epoch:{},Train Loss:{:.4f},Train Acc:{:.4f},Test Loss:{:.4f},Test Acc:{:.4f}'
             .format(epoch,train_loss/len(train_loader),train_acc/len(train_loader),
                    eval_loss/len(test_loader),eval_acc/len(test_loader)))

4. 分析原因

定位出错位置

Traceback (most recent call last):
  File "train.py", line 73, in <module>
    out = model(img)
  File "/home/gzdx/anaconda3/envs/Torch/lib/python3.7/site-packages/torch/nn/modules/module.py", line 889, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/home/gzdx/wyf/PARAD/model.py", line 48, in forward
    x = self.conv1(x)
  File "/home/gzdx/anaconda3/envs/Torch/lib/python3.7/site-packages/torch/nn/modules/module.py", line 889, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/home/gzdx/anaconda3/envs/Torch/lib/python3.7/site-packages/torch/nn/modules/container.py", line 119, in forward
    input = module(input)
  File "/home/gzdx/anaconda3/envs/Torch/lib/python3.7/site-packages/torch/nn/modules/module.py", line 889, in _call_impl
    result = self.forward(*input, **kwargs)
  File "/home/gzdx/anaconda3/envs/Torch/lib/python3.7/site-packages/torch/nn/modules/conv.py", line 399, in forward
    return self._conv_forward(input, self.weight, self.bias)
  File "/home/gzdx/anaconda3/envs/Torch/lib/python3.7/site-packages/torch/nn/modules/conv.py", line 396, in _conv_forward
    self.padding, self.dilation, self.groups)
RuntimeError: Expected 4-dimensional input for 4-dimensional weight [32, 1, 5, 5], but got 2-dimensional input of size [32, 784] instead

可以看到这句提示,大致就是我们传入的数据输入到CNN网络,然后由于维度不同导致的。因为我们输入的是四维,但是得到的却是二维。

  File "train.py", line 73, in <module>
    out = model(img)

5.解决办法

对于这种问题网上给出了很多中不同的方案,这个哦个人也是参考我网上别人给出的一点想法然后自己修改了下,错误就解决了,如下所示:

for i,data in enumerate(train_loader):
        #前向传播,将图片数据传入模型中
        # out输出10维,分别是各数字的概率,即每个类别的得分
        inputs, labels = data
        inputs,labels = data[0].to(device), data[1].to(device)
        # inputs torch.Size([32, 1, 28, 28])
        out = model(inputs)

解决办法也是很简单,就是将上面训练开始阶段将数据按照这种读取方式来赋值,然后在传入到model里面就不会出现上面那种错误了。

6. 完整代码

import numpy as np
import model
import torch

#导入PyTorch内置的mnist数据
from torchvision.datasets import mnist

#导入预处理模块
from torchvision import transforms
from torch.utils.data import DataLoader

#导入神经网络工具
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim

#定义后面要用到的超参数
train_batch_size = 32
test_batch_size = 32

#学习率与训练次数
learning_rate = 0.01
nums_epoches = 50

#优化器的时候使用的参数
lr = 0.1
momentum = 0.5

#用compose来定意预处理函数
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5],[0.5])])

#下载数据,在工程文件夹里新建一个data文件夹储存下载的数据
train_dataset = mnist.MNIST('./data', train=True, transform=transform, target_transform=None, download=False)
test_dataset = mnist.MNIST('./data', train=False, transform=transform, target_transform=None, download=False)

#数据加载器,组合数据集和采样器,并在数据集上提供单进程或多进程迭代器
train_loader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True, num_workers=0)
test_loader = DataLoader(test_dataset, batch_size=test_batch_size, shuffle=False)

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

#实例化网络,只考虑使用CPU
model = model.MNIST_Model(1)
net = model.to(device)
#定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
#momentum:动量因子有什么用处?
optimizer = optim.SGD(model.parameters(),lr=lr,momentum=momentum)




#开始训练 先定义存储损失函数和准确率的数组
losses = []
acces = []
#测试用
eval_losses = []
eval_acces = []

for epoch in range(nums_epoches):
    #每次训练先清零
    train_loss = 0
    train_acc = 0
    #将模型设置为训练模式
    model.train()

    #动态学习率
    if epoch%5 == 0:
        optimizer.param_groups[0]['lr'] *= 0.1
    for i,data in enumerate(train_loader):
        #前向传播,将图片数据传入模型中
        # out输出10维,分别是各数字的概率,即每个类别的得分
        inputs, labels = data
        inputs,labels = data[0].to(device), data[1].to(device)
        out = model(inputs)
        #这里注意参数out是64*10,label是一维的64
        loss = criterion(out,labels)
        #反向传播
        #optimizer.zero_grad()意思是把梯度置零,也就是把loss关于weight的导数变成0
        optimizer.zero_grad()
        loss.backward()
        #这个方法会更新所有的参数,一旦梯度被如backward()之类的函数计算好后,我们就可以调用这个函数
        optimizer.step()
        
        #记录误差 
        train_loss += loss.item()
        
        #计算分类的准确率,找到概率最大的下标
        _,pred = out.max(1)
        num_correct = (pred == labels).sum().item() #记录标签正确的个数
        acc = num_correct/inputs.shape[0]
        train_acc += acc
    losses.append(train_loss/len(train_loader))
    acces.append(train_acc/len(train_loader))
    print('Finished Training') 

    # 保存模型
    PATH = './model/mnist_net.pth'
    torch.save(net.state_dict(), PATH)
    
    eval_loss = 0
    eval_acc = 0
    model.eval()
    for i,data in enumerate(test_loader):
        inputs, labels = data
        inputs,labels = data[0].to(device), data[1].to(device)
        out = model(inputs)
        loss = criterion(out,labels)
        
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        
        eval_loss += loss.item()
        
        _,pred = out.max(1)
        num_correct = (pred == labels).sum().item()
        acc = num_correct/inputs.shape[0]
        eval_acc += acc
    eval_losses.append(eval_loss/len(test_loader))
    eval_acces.append(eval_acc/len(test_loader))
    

    print('epoch:{},Train Loss:{:.4f},Train Acc:{:.4f},Test Loss:{:.4f},Test Acc:{:.4f}'
             .format(epoch,train_loss/len(train_loader),train_acc/len(train_loader),
                    eval_loss/len(test_loader),eval_acc/len(test_loader)))




7. 参考文献

1.pytorch学习笔记—搭建CNN识别MNIST

2.使用Pytorch框架的CNN网络实现手写数字(MNIST)识别

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RuntimeError: Expected 4-dimensional input for 4-dimensional weight [32, 1, 5, 5] 的相关文章

  • HDF5 库错误

    我正在使用以下 1 VS 2010 C 2 调试Win 32 3 图书馆从这里 http www hdfgroup org HDF5 release obtain5 html http www hdfgroup org HDF5 relea
  • 角度 4 单击按钮功能未触发

    我正在尝试检查文本输入是否为空或不在角度 4 中 我没有为此使用表单 这只是一个输入字段 当我在下面的按钮中执行 addLocaton 函数时 需要进行检查 我的输入字段
  • TensorFlow:在训练时更改变量

    如果我将输入管道从 feed dict 更改为 tf data dataset 如何在每次迭代后的训练期间更改网络内参数的值 澄清一下 旧代码看起来像这样 Define Training Step model is some class t
  • 根据用户输入使用 Jquery 显示/隐藏字段

    li class numeric optional li
  • PowerShell 参数 - “术语‘param’未被识别为 cmdlet 的名称”

    考虑 notepad Starts Notepad Get Process notepad Finds the processes named notepad param Parameter Mandatory true string Pr
  • 程序不等待 cin

    int x 0 string fullname float salary float payincrease float newsal float monthlysal float retroactive while x lt 3 cout
  • 将键码转换为相关的显示字符

    在 C Windows Forms 项目中 我有一个不提供 KeyPressed 事件的控件 它是一个 COM 控件 ESRI 映射 它仅提供 KeyUp 和 KeyDown 事件 包含关键事件参数 http msdn microsoft
  • 如何使用文本输入来定位?

    我想使用 jQuery 通过文本框转到锚点 例如 我想使用以下形式
  • 编辑时可以在文本框控件内使用 Angular 的管道格式化程序吗?

    我已经声明了一种将大数字分成三位数组的格式 并像这样经常使用它 div Huge number i am huge make threesome div 现在 有一个对相应功能的请求 但在像这样的输入控件中实现
  • 在 Chrome 中显示输入 type=date-local 的秒数

    在谷歌浏览器中 如果我设置 type 输入的值datetime local包含秒的时间 其中秒值为 0 Chrome 决定不在输入中显示秒值 这意味着用户根本无法设置秒 例如 如果我将值设置为2013 10 24T20 36 01然后Chr
  • 如何检测 Android 上的触摸输入

    现在我想做的就是检测何时按下屏幕 然后显示一条日志消息以确认它发生了 到目前为止 我的代码是根据 CameraPreview 示例代码修改的 它最终会拍摄一张照片 因此大部分代码位于扩展 SurfaceView 的类中 SDK 中示例代码的
  • Windows BlockInput 功能不起作用

    Why BlockInput不工作 include
  • JQuery 找不到我的元素。为什么?

    更新 愚蠢的我没有注意到案例不准确 我为此苦苦挣扎了 30 多分钟 而你们在不到 5 分钟的时间里就看到了我的问题 感谢您为我节省了很多悲伤 无论如何 我对编程还是个新手 我需要学习如何留意这样的小事情 但非常感谢 它甚至没有闪过我的脑海
  • 修复 IE8 中的“未知运行时错误”[关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我没有看到其他人真正努力实现我的目标 很多人想通过innerHTML属性替换一些节点 但是 我不仅想这样做 而且我还想用javascrip
  • 一行输入多个数字

    我想知道如何在一行上接受多个数字 而无需事先确切知道有多少个数字 例如 如果我有1 2 3 4作为输入我可以使用 std cin gt gt a gt gt b gt gt c gt gt d 但如果我不知道数量是 4 那么我就不能使用这种
  • 禁用输入中的空格,并允许后退箭头?

    我试图禁用用户名文本字段中的空格 但是我的代码也禁用后退箭头 有什么办法也允许后退箭头吗 function var txt input UserName var func function txt val txt val replace s
  • Angular - CSS - 自定义类型=文件输入,如何使用按钮而不是标签?

    我制作了一个类型为 file 的自定义输入字段 因为我不喜欢默认的输入字段 为了实现这一目标 我做了
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • Javascript:更改输入值时设置光标位置

    当您输入公式时 我试图在我的应用程序中重现类似于 Microsoft Excel Google Sheets 的用户体验 并且您可以使用不同的公式和变量来自动完成下拉菜单 为此 在验证自动完成功能后 我希望能够控制光标的位置 例如 如果我输
  • 如何将用户输入与枚举值映射?

    我有一个基本的enum宣言 enum Title Prof Dr Mr Mdm Mrs Miss NA 我正在尝试将用户输入 0 1 2 3 4 5 AnyNumber 映射为正确的值enum像这样 std map

随机推荐

  • C++串口通信

    一 串口通信的基本原理 串口的本质功能是作为 CPU 和串行设备间的编码转换器 当数据从 CPU 经过串行端口发送出去时 xff0c 字节数据转换为串行的位 xff08 bit xff09 xff1b 在接收数据时 xff0c 串行的位被转
  • 死锁的四个必要条件以及处理策略

    一 什么是死锁 死锁是指两个或两个以上的进程 xff08 线程 xff09 在运行过程中因争夺资源而造成的一种僵局 例如 xff0c 某计算机系统中只有一台打印机和一台输入设备 xff0c 进程P1正占用输入设备 xff0c 同时又提出使用
  • EM算法简介

    1 简介 EM算法是一种迭代优化策略 xff0c 由于它的计算方法中每一次迭代都分两步 xff0c 其中一个为期望步 xff08 E步 xff09 xff0c 另一个为极大步 xff08 M步 xff09 xff0c 所以算法被称为EM算法
  • 三菱PLC MC协议

    1 MC协议的目的 xff1a 允许外部设备读写PLC内部寄存器 2 协议格式 xff1a 通讯方式有RS485和TCP IP两种 xff0c 通讯格式有很多种 xff1a 3E 3C 4C 4E帧格式 xff0c 通讯内容分为二进制和AS
  • find和find_if用法

    一 find的用法 STL容器中有很多find xff0c 比如说set xff0c map 他们内部都有内置的find函数 xff0c 一般情况下 xff0c 如果我们用到这些容器 xff0c 那么我们直接用它的内置find就可以了 xf
  • QTreeView节点拖放

    拖放操作分为拖动 Drag 和放置 Drop 两种操作 xff0c 当拖动时需要把拖动的数据进行存储 称为编码 xff0c 数据存储为QMimeData类型的对象 称为放置数据 xff0c 当执行放置操作时需要把存储的数据读取出来 称为解码
  • OOD七大原则

    1 单一职责原则 xff08 Single Responsibility Principle xff09 一个类或一个接口只有一个职责 xff0c 有且仅有一个原因引起变化 2 开闭原则 xff08 Open Closed Principl
  • 微服务探索之路05篇jenkins构建net6和vue docker镜像到Harbor自动更新k8s服务镜像

    从1 4篇已经学习了docker Harbor k8s的基本用法 接下来进阶一下使用jenkins结合起来做到自动部署项目 1 安装jenkins 1 1前提条件 docker环境 xff0c 可参考第01篇安装docker本文使用的是li
  • linux为用户添加sudo权限

    一 linux为用户添加sudo权限 用sudo时提示 34 xxx is not in the sudoers file This incident will be reported 其中XXX是你的用户名 xff0c 这是止当前用户没有
  • pixhawk多线程编程

    金错刀 pixhawk多线程程序编写 pixhawk源码多线程程序的编写 主要是针对pixhawk源码进行第二次开发的学习笔记 xff0c 记录下以便日后查阅 期望达到的目标 添加一个app应用 xff0c 在nsh的后台中运行该应用 xf
  • [视觉惯性导航系列]相机标定工具--kalibr

    前言 有很多博主推荐kalibr进行相机标定 我参考博主 纷繁中淡定 Kalibr标定Intel D435i相机 完成相机标定 但是kalibr在安装过程中会出现很多令人头秃的报错信息 综合了网上好多人的方法 才完成 本文做一点记录 本文不
  • C++ Exception

    Exception type Derived types scattered throughout different library headers bad alloc Exception thrown on failure alloca
  • 什么是最优化问题(Optimization Problem)?

    最优化问题是人们在科学研究和生产实践中经常遇到的问题 1 人类所从事的一切生产或者社会活动均是有目的的 其行为总是在特点的价值观念或者审美取向的支配下进行的 xff0c 因此经常面临一个可行的甚至是最优化的方案的决策问题 这就是最优化问题
  • 单例模式(java代码实现)

    应用单例模式时 xff0c 类只能有一个对象实例 xff0c 这么做的目的是避免不一致状态 饿汉式单例 xff1a xff08 立即加载 xff09 饿汉式单例 public class Singleton1 指向自己实例的私有静态引用 x
  • C++函数后面加“:”的含义

    转载 xff1a C 43 43 函数后面加 xff1a 的含义 hhd1988的专栏 CSDN博客 1 c 43 43 成员函数后面跟 xff1a 表示的是赋值 xff0c 这是c 43 43 的特性 如下 xff1a A int aa
  • 因子图(factor graph)

    因子图 xff08 factor graph xff09 Factor Graph 是概率图的一种 xff0c 概率图有很多种 xff0c 最常见的就是Bayesian Network 贝叶斯网络 和Markov Random Fields
  • 词袋模型(Bag of Features,BOF)

    Bag of Features xff08 BOF xff09 对于程序而言这个人就是一堆像素嘛 xff0c 让它直接找的话它只能一个个像素的去比较然后返回最接近的了 xff08 近邻算法 xff09 但是现实中物体的形状颜色会发生变化 x
  • SNMPv3基于用户的安全模型USM及消息格式

    一 USM相关网址 SNMPv3使用了基于用户的安全模型USM RFC 3411 Architecture for SNMP Frameworks http www ietf org rfc rfc3411 txtRFC 3414 User
  • 超详细的python搭建区块链(下)

    在前面 超详细的python搭建区块链 xff08 中 xff09 我们搭建了一个简单的区块链 在这个简单的区块链能够实现交易 挖矿等基本功能 不过 xff0c 区块链上的节点应该是分散的 如果它们是分散的 xff0c 我们究竟如何确保它们
  • RuntimeError: Expected 4-dimensional input for 4-dimensional weight [32, 1, 5, 5]

    文章目录 1 问题引入2 运行报错3 代码4 分析原因5 解决办法6 完整代码7 参考文献 1 问题引入 今天在使用pytorch训练一个模型的 xff0c 数据集的读取是使用pytorch自带的函数来进行读取和预处理的 xff0c 网络使