input_size = 24001#excel数据点数
dir_list = os.listdir("E:/pythonProject/doing")#实验数据路径,./表示当下文件夹
all_data_list=[]
all_label_list=[]
for i in range(len(dir_list)):
label = int(dir_list[i].split("_")[-1])
print(label)
dir = dir_list[i]
file_list = os.listdir("./doing/"+dir)
print(file_list)
tmp_data_list = []
tmp_label_list = []
for j in range(len(file_list)):
filename = "./doing/"+dir+"/"+file_list[j]
#print(filename)
tmp_df = pd.read_excel(filename)
tmp_data = np.array(tmp_df.values[:, 1])
# print(len(tmp_data))
tmp_data = F.interpolate(torch.tensor(tmp_data).unsqueeze(0).unsqueeze(0).unsqueeze(0),
(1, input_size)).squeeze(0).squeeze(0).squeeze(0).numpy()
#plt.plot(tmp_data)
#plt.show()
print(tmp_data.shape)
tmp_data_list.append(tmp_data)
tmp_label_list.append(label)
tmp_data = np.array(tmp_data_list)
tmp_label = np.array(tmp_label_list)
all_data_list.append(tmp_data)
all_label_list.append(tmp_label)
all_data = np.array(all_data_list).reshape(-1,input_size)
all_data = (all_data - np.mean(all_data)) / (np.max(all_data) - np.min(all_data))
print(all_data.shape)
label = np.array(all_label_list)
label = label.reshape(label.shape[0]*label.shape[1])
print(label.shape)
class Load_dataset(data.Dataset):
def __init__(self, data, label):
self.len = label.shape[0]
self.data = data
self.label = label
def __len__(self):
return self.len
def __getitem__(self, idx):
x = self.data[idx]
y = self.label[idx]
return x, y
def collate_fn(self, data):
x, y = zip(*data)
return x, y
full_dataset = Load_dataset(all_data, label)
train_num = 80
test_num = 20
train_set, test_set = torch.utils.data.random_split(full_dataset, [train_num, test_num],
generator=torch.Generator().manual_seed(6))
loader_train = torch.utils.data.DataLoader(train_set, batch_size=int(train_num / 2), shuffle=True)
loader_test = torch.utils.data.DataLoader(test_set, batch_size=1, shuffle=False)
# 模型定义函数
class model(nn.Module):
def __init__(self):
super(model, self).__init__()
self.conv1 = nn.Conv1d(in_channels=1, out_channels=64, kernel_size=5, padding=2)
self.pool1 = nn.MaxPool1d(kernel_size=2, stride=2)
self.conv2 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=5, padding=2)
self.pool2 = nn.MaxPool1d(kernel_size=2, stride=2)
self.conv3 = nn.Conv1d(in_channels=128, out_channels=256, kernel_size=5, padding=2)
self.pool3 = nn.MaxPool1d(kernel_size=2, stride=2)
self.fc = nn.Linear(input_size * 4, 10)
def forward(self, x):
y = F.relu(self.conv1(x))
y = self.pool1(y)
y = F.relu(self.conv2(y))
y = self.pool2(y)
y = F.relu(self.conv3(y))
y = self.pool3(y)
y = y.reshape(y.shape[0], -1)
y = self.fc(y)
return y
net = model()
opt = torch.optim.Adam(net.parameters(), lr=0.001)
best_test_acc = 0
patience = 0
train_loss = []
train_acc = []
test_acc = []
for epoch in range(100):
net.train()
pred_list = []
label_list = []
for i, (x, y) in enumerate(loader_train):
pred = net(x.unsqueeze(1).float())
loss = torch.nn.CrossEntropyLoss()(pred, y.long())
acc = torch.mean((y == pred.argmax(1)).float())
print(epoch, i)
print("train_loss:", loss.item())
print("train_acc", round(acc.item(), 4))
train_acc.append(acc.item())
train_loss.append(loss.item())
opt.zero_grad()
loss.backward()
opt.step()
net.eval()
acc = 0
for i, (x, y) in enumerate(loader_test):
pred = net(x.unsqueeze(1).float())
pred_list.append(pred.argmax(1).item())
label_list.append(y.item())
acc += torch.sum((y == pred.argmax(1)).float())
acc = acc / test_num
if acc > best_test_acc:
patience = 0
best_test_acc = acc.item()
best_pred_list = pred_list
torch.save(net.state_dict(), 'net_best.pkl')
else:
patience += 1
# if patience == 3:
# break
print("test_acc", round(acc.item(), 4))
test_acc.append(acc.item())
print("best_test_acc", round(best_test_acc, 4))
# 损失函数图
import matplotlib.pyplot as plt
print()
plt.plot(train_loss)
train_acc= 'lossrecord/loss.txt'
plt.xlabel("step", font='Times New Roman', fontsize=16)
plt.ylabel("loss", font='Times New Roman', fontsize=16)
plt.show()
from sklearn.metrics import confusion_matrix, ConfusionMatrixDisplay
confusion_mat = confusion_matrix(np.array(label_list), np.array(best_pred_list))
disp = ConfusionMatrixDisplay(confusion_matrix=confusion_mat)
disp.plot(
include_values=True,
cmap="viridis",
ax=None,
xticks_rotation="horizontal",
values_format="d"
)
plt.show()
报错“RuntimeError: mat1 and mat2 shapes cannot be multiplied (40x96000 and 96004x10)”,大神们,这个怎么修改啊?让这个py正常工作。
提示两个矩阵不能相乘,提供的数据有问题。A矩阵3行4列 * B矩阵4行3列,你的数据A矩阵40行96000 列,B矩阵96004行10列,这俩咋相乘呢/
基于ChatGPT的回答:
这是一个矩阵乘法的错误。矩阵乘法要求第一个矩阵的列数要等于第二个矩阵的行数,但是在这个错误中,第一个矩阵的列数为96000,而第二个矩阵的行数为96004,这两个数不相等,因此无法进行矩阵乘法运算。
将第一个矩阵的列数修改为24001,与input_size相等即可解决矩阵乘法错误。即将以下代码:
all_data = np.array(all_data_list).reshape(-1,96000)
修改为:
all_data = np.array(all_data_list).reshape(-1,input_size)
基于new Bing的回答:
问题可能出在全连接层的输入数据形状与权重矩阵不匹配。你可以检查一下全连接层的输入数据形状,确保它与权重矩阵匹配。
还有一个问题:在计算损失函数时,你使用了
torch.nn.CrossEntropyLoss()
但是你没有将其实例化。正确的做法应该是先实例化损失函数,然后再调用它。
引用new bing作答:
错误消息“RuntimeError:mat1和mat2形状无法相乘(40x96000和96004x10)”表示矩阵乘法运算中存在大小不匹配。要修复此错误,您需要修改其中一个或两个矩阵的形状,以便它们与乘法兼容。
在这种情况下,当试图计算模型中的完全连接层时,似乎出现了问题。因为模型中最终完全连接层的大小 (self.fc) 期望输入的形状为 (batch_size, input_size * 4 )(其中 input_size 为 24001)但传递给模型的输入形状具有不同的形状((batch_size,1,input_size))。
要解决此问题,您可以修改模型类中的前向函数以在输入张量通过全连接层之前对其进行整形。 可以替换以下行:
y = y.reshape(y.shape[0], -1)
替换为:
y = y.view(y.size(0), -1)
y = y.view(y.size(0), -1) 行将张量 y 重塑为 (batch_size, input_size * 4) 的形状,然后再将其传递给全连接层。 这应该可以解决您遇到的错误。
这个错误的原因是矩阵的维度不匹配,无法进行矩阵乘法运算。具体来说,mat1的列数应该等于mat2的行数,才能进行矩阵乘法运算。
解决这个问题的方法是调整矩阵的维度,使得它们可以进行矩阵乘法运算。具体来说,如果mat1的维度是(40, 96000),mat2的维度是(96004, 10),那么可以通过transpose函数将mat2的维度调整为(10, 96004),然后进行矩阵乘法运算,得到一个维度为(40, 10)的矩阵。
下面是一个示例代码:
import torch
mat1 = torch.randn(40, 96000)
mat2 = torch.randn(96004, 10)
mat2_t = mat2.transpose(0, 1)
result = torch.mm(mat1, mat2_t)
print(result.shape) # 输出 (40, 10)
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
这个问题是因为全连接层的输入维度不匹配导致的。在模型定义函数中,全连接层的输入维度应该是卷积层输出的展平向量大小,即input_size * 4 * 1
,而不是input_size * 4
,修改方式如下:
class model(nn.Module):
def __init__(self):
super(model, self).__init__()
self.conv1 = nn.Conv1d(in_channels=1, out_channels=64, kernel_size=5, padding=2)
self.pool1 = nn.MaxPool1d(kernel_size=2, stride=2)
self.conv2 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=5, padding=2)
self.pool2 = nn.MaxPool1d(kernel_size=2, stride=2)
self.conv3 = nn.Conv1d(in_channels=128, out_channels=256, kernel_size=5, padding=2)
self.pool3 = nn.MaxPool1d(kernel_size=2, stride=2)
self.fc = nn.Linear(input_size * 4 * 1, 10) # 修改全连接层输入维度
def forward(self, x):
y = F.relu(self.conv1(x))
y = self.pool1(y)
y = F.relu(self.conv2(y))
y = self.pool2(y)
y = F.relu(self.conv3(y))
y = self.pool3(y)
y = y.reshape(y.shape[0], -1)
y = self.fc(y)
return y
同时,你的数据集划分方式可能存在问题,因为batch_size=int(train_num / 2)
将导致第一个batch大小为20,而第二个batch大小为40,可能不是你想要的。建议尝试使用其他方式进行数据集划分,如随机划分等。
如果我的回答解决了您的问题,请采纳!
引用chatGPT作答,该代码的报错是因为在模型定义函数model中,全连接层nn.Linear的输入大小不正确。当前输入大小为input_size * 4,而input_size的值为24001,这意味着全连接层的输入大小为96004。但是模型的输出大小为10。这两个大小不匹配,因此出现了“mat1和mat2的形状不能相乘”的错误。
要解决这个问题,需要重新计算全连接层的输入大小。根据卷积层和池化层的参数,可以计算出卷积层输出的大小为256,然后在3个池化层之后,输出大小将变为256/2/2/2=32。因此,全连接层的输入大小应该为32 * 256 = 8192。
下面是修改后的model代码:
class model(nn.Module):
def __init__(self):
super(model, self).__init__()
self.conv1 = nn.Conv1d(in_channels=1, out_channels=64, kernel_size=5, padding=2)
self.pool1 = nn.MaxPool1d(kernel_size=2, stride=2)
self.conv2 = nn.Conv1d(in_channels=64, out_channels=128, kernel_size=5, padding=2)
self.pool2 = nn.MaxPool1d(kernel_size=2, stride=2)
self.conv3 = nn.Conv1d(in_channels=128, out_channels=256, kernel_size=5, padding=2)
self.pool3 = nn.MaxPool1d(kernel_size=2, stride=2)
self.fc = nn.Linear(8192, 10)
def forward(self, x):
y = F.relu(self.conv1(x))
y = self.pool1(y)
y = F.relu(self.conv2(y))
y = self.pool2(y)
y = F.relu(self.conv3(y))
y = self.pool3(y)
y = y.reshape(y.shape[0], -1)
y = self.fc(y)
return y