[MindSpore]训练LeNet5报错x1_col,x2_row,For ‘MatMul‘, the input dimensions must be equal

mindspore1.6.1 cpu版本

报错信息:
ValueError: For 'MatMul', the input dimensions must be equal, but got 'x1_col': 256 and 'x2_row': 400. And 'x' shape [8, 256](transpose_a=False), 'y' shape [120, 400](transpose_b=True).

这句报错描述的是我们在MatMul算子中进行张量的计算时

出现了不符合线性代数中乘法运算的情况:第一个张量的列数 不等于 第二个张量的行数

初看这个报错可能觉得我上面那句话是错的,请注意看看 transpose_a = False这个属性,代表当前的张量(矩阵)是否已经转置

问题分析:
1:是数据集中图片大小问题吗?
本实验使用的是MNIST数据集,使用mindspore.MnistDataset进行加载
图片的大小为28*28与这里提到的数字无关,不是这个问题

2.经过检查 400这个数字与网络中的全连接层有关
全连接层源码
上图是全连接层的源码部分片段,在这里可以看到在construct中是有这样一个matmul操作
x = self.matmul(x, self.weight)

3.检查报错原因:
ValueError: For 'MatMul', the input dimensions must be equal, but got 'x1_col': 256 and 'x2_row': 400. And 'x' shape [8, 256](transpose_a=False), 'y' shape [120, 400](transpose_b=True).
修改原代码中400的地方
是第一个全连接层的大小出错了
改为(256,120)

想要复现的宝子们看下面:
(我是在vscode的jupyter中运行的,不同的方法运行可能输出不一样)
数据集下载:(在这个目录下打开shell工具(例如MobaXterm))
运行如下指令

mkdir -p ./datasets/MNIST_Data/train ./datasets/MNIST_Data/test
wget -NP ./datasets/MNIST_Data/train https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/train-labels-idx1-ubyte
wget -NP ./datasets/MNIST_Data/train https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/train-images-idx3-ubyte
wget -NP ./datasets/MNIST_Data/test https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/t10k-labels-idx1-ubyte
wget -NP ./datasets/MNIST_Data/test https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/t10k-images-idx3-ubyte
tree ./datasets/MNIST_Data

完整源代码:

import numpy as np
import mindspore
import mindspore.nn as nn
from mindspore import Tensor,Model
from mindspore import  dtype as mstype
from mindspore.train.callback import LossMonitor
import mindspore.dataset.transforms.c_transforms as C
import mindspore.dataset.vision.c_transforms as CV
import mindspore.dataset as ds
import os
import argparse

parser = argparse.ArgumentParser(description='MindSpore LeNet Example')
parser.add_argument('--device_target', type=str, default="CPU", choices=['Ascend', 'GPU', 'CPU'])


DATA_DIR = "./datasets/MNIST_Data/train"
# DATA_DIR = "./datasets/cifar-10-batches-bin/train"

if not os.path.exists(DATA_DIR):
    os.makedirs(DATA_DIR)
#采样器
sampler = ds.SequentialSampler(num_samples=5)

# dataset = ds.Cifar100Dataset(DATA_DIR,sampler=sampler)

dataset = ds.MnistDataset(DATA_DIR,sampler=sampler) #这个是MNIST数据集
# dataset = ds.Cifar10Dataset(DATA_DIR,sampler=sampler) #这个是Cifar10数据集

class LeNet5(nn.Cell):
    def __init__(self,num_class=10,num_channel = 1):
    # 初始化网络
        super(LeNet5,self).__init__()
        # 定义所需要的运算
        self.conv1 = nn.Conv2d(num_channel,6,5,pad_mode='valid') # 卷积
        self.conv2 = nn.Conv2d(6,16,5,pad_mode='valid')
        self.fc1 = nn.Dense(256,120) # 全连接层
        # self.fc1 = nn.Dense(16*5*5,120) # 全连接层
        self.fc2 = nn.Dense(120,84)
        self.fc3 = nn.Dense(84,num_class)
        self.max_pool2d = nn.MaxPool2d(kernel_size=2,stride=2)# 最大池化-降采样
        self.relu = nn.ReLU() # 激活函数
        self.flatten = nn.Flatten()# flatten 扁平的意思=> 将原来的高维数组换成只有 一行 的数组 列数是之前的各维度之积

    # 定义网络构建函数
    def construct(self,x):
        # 构建前向网络
        x = self.conv1(x)
        x = self.relu(x)
        x = self.max_pool2d(x)
        x = self.conv2(x)
        x = self.relu(x)
        x = self.max_pool2d(x)
        x = self.flatten(x)
        print(x.shape)
        print(self.shape)
        print(self.weight)
        x = self.fc1(x)
        x = self.relu(x)
        x = self.fc2(x)
        x = self.relu(x)
        x = self.fc3(x)
        return x    

#初始化网路
net = LeNet5()
for m in net.parameters_and_names():
    print(m)
    
#定义超参
epoch = 10
batch_size = 64
learning_rate = 0.1
 
#构建数据集
sampler = ds.SequentialSampler(num_samples=128)
dataset = ds.MnistDataset(DATA_DIR,sampler = sampler)

#数据类型的转换
type_cast_op_image = C.TypeCast(mstype.float32)
type_cast_op_label = C.TypeCast(mstype.int32)

#数据序列读取方式
HWC2CHW = CV.HWC2CHW()

#构建数据集
dataset = dataset.map(operations=[type_cast_op_image,HWC2CHW],input_columns="image")
dataset = dataset.map(operations=type_cast_op_label,input_columns="label")
dataset = dataset.batch(batch_size)

print("\n")
#传入定义的超参
for p in net.trainable_params():
    print(p)

optim = nn.SGD(params=net.trainable_params(),learning_rate=learning_rate)# 自动微分反向传播
loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True,reduction='mean') # 交叉熵损失函数

#开始训练
model = Model(net,loss_fn=loss,optimizer=optim)
model.train(epoch=epoch,train_dataset=dataset,callbacks=LossMonitor())

输出:

[WARNING] ME(14204:8992,MainProcess):2022-04-29-13:57:28.537.104 [mindspore\train\model.py:536] The CPU cannot support dataset sink mode currently.So the training process will be performed with dataset not sink.
Output exceeds the size limit. Open the full output data in a text editor
('conv1.weight', Parameter (name=conv1.weight, shape=(6, 1, 5, 5), dtype=Float32, requires_grad=True))
('conv2.weight', Parameter (name=conv2.weight, shape=(16, 6, 5, 5), dtype=Float32, requires_grad=True))
('fc1.weight', Parameter (name=fc1.weight, shape=(120, 256), dtype=Float32, requires_grad=True))
('fc1.bias', Parameter (name=fc1.bias, shape=(120,), dtype=Float32, requires_grad=True))
('fc2.weight', Parameter (name=fc2.weight, shape=(84, 120), dtype=Float32, requires_grad=True))
('fc2.bias', Parameter (name=fc2.bias, shape=(84,), dtype=Float32, requires_grad=True))
('fc3.weight', Parameter (name=fc3.weight, shape=(10, 84), dtype=Float32, requires_grad=True))
('fc3.bias', Parameter (name=fc3.bias, shape=(10,), dtype=Float32, requires_grad=True))


Parameter (name=conv1.weight, shape=(6, 1, 5, 5), dtype=Float32, requires_grad=True)
Parameter (name=conv2.weight, shape=(16, 6, 5, 5), dtype=Float32, requires_grad=True)
Parameter (name=fc1.weight, shape=(120, 256), dtype=Float32, requires_grad=True)
Parameter (name=fc1.bias, shape=(120,), dtype=Float32, requires_grad=True)
Parameter (name=fc2.weight, shape=(84, 120), dtype=Float32, requires_grad=True)
Parameter (name=fc2.bias, shape=(84,), dtype=Float32, requires_grad=True)
Parameter (name=fc3.weight, shape=(10, 84), dtype=Float32, requires_grad=True)
Parameter (name=fc3.bias, shape=(10,), dtype=Float32, requires_grad=True)
epoch: 1 step: 1, loss is 2.302509069442749
epoch: 1 step: 2, loss is 2.302182197570801
epoch: 2 step: 1, loss is 2.3014421463012695
epoch: 2 step: 2, loss is 2.299675941467285
epoch: 3 step: 1, loss is 2.3004305362701416
epoch: 3 step: 2, loss is 2.2972540855407715
epoch: 4 step: 1, loss is 2.2994704246520996
...
epoch: 9 step: 1, loss is 2.2953572273254395
epoch: 9 step: 2, loss is 2.284273386001587
epoch: 10 step: 1, loss is 2.294651746749878
epoch: 10 step: 2, loss is 2.282334089279175
这个错误信息是在使用Python中的`scipy.optimize.linprog`函数时出现的,该函数用于求解线性规划(Linear Programming)问题。`linprog`函数要求线性约束条件矩阵`A_ub`必须是二维的(即行数x列数),并且它的列数应当与目标函数系数向量`c`的长度相等。 当你看到`Invalid input for linprog: A_ub must have exactly two dimensions`,这意味着你提供的`A_ub`矩阵不是二维的。可能是矩阵的形状不正确,比如它不是一个矩形,或者列数与`c`的长度不符。例如,如果你有一个包含多列的矩阵,或者列数比`c`的元素少,都会导致这个错误。 检查一下`A_ub`的维度和`c`的长度是否匹配。确保`A_ub`是一个只有一对维度的数组,其列数等于`c`的长度。如果`A_ub`是多维的,试着将其转置为适合的形式;如果列数不够,你需要补充更多的列,或者调整你的约束条件。 ```python # 假设你的A_ub和c像这样: A_ub = [[1, 2], [3, 4]] # 这样是正确的,因为它是一维数组,转换后是2x1 c = [5, 6] # 这里长度应与A_ub的列数相同 # 如果A_ub原本是二维但列数不对: # A_ub = [[1, 2, 3], [4, 5, 6]] # 这样是错误的,因为列数比c长 # 需要调整为: # A_ub = np.column_stack([A_ub[:,0], A_ub[:,1]]) # 或者手动去掉多余的列 # 如果c长度不对: # c = [5] # 这样是错误的,因为长度比A_ub的列数短 # 需要根据实际需求添加或改变c的长度 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值