import pandas as pd
from sklearn.model_selection import GridSearchCV
from sklearn.metrics import accuracy_score
import torch
import torch.nn as nn
import torch.optim as optim
from sklearn.preprocessing import MinMaxScaler
# 加载数据集并进行预处理
data=pd.read_excel('D:\office文件\状态退化评价/0.5.xlsx','Sheet3')
# 打开现有的Excel文件
data=data.values
y=data[:,7]
X=data[:,4:7]
from sklearn.model_selection import train_test_split
# 假设有一个数据集X和标签集y
#inputs, X_test, labels, y_test = train_test_split(inputs, labels, test_size=0.1, random_state=42)
inputs= X[:48]
X_test = X[-12:]
labels = y[:48]
y_test = y[-12:]
inputs = inputs.reshape(-1, 3)
labels = labels.reshape(-1, 1)
X_test = X_test .reshape(-1, 3)
y_test = y_test.reshape(-1, 1)
# 定义CNN模型
class CNN(nn.Module):
def __init__(self):
super(CNN, self).__init__()
self.fc1 = nn.Linear(3, 12)
self.fc2 = nn.Linear(12, 100)
self.conv1 = nn.Conv2d(1, 12, kernel_size=3, stride=1, padding=1)
#self.pool1 = nn.MaxPool2d(kernel_size=2)
self.conv2 = nn.Conv2d(12, 12, kernel_size=3, stride=1, padding=1)
self.conv3 = nn.Conv2d(12, 12, kernel_size=3, stride=1, padding=1)
#self.pool3 = nn.MaxPool2d(kernel_size=2)
self.conv4 = nn.Conv2d(12, 12, kernel_size=3, stride=1, padding=1)
self.pool4 = nn.MaxPool2d(kernel_size=2)
self.conv5 = nn.Conv2d(12, 12, kernel_size=3, stride=1, padding=1)
self.conv6 = nn.Conv2d(12, 12, kernel_size=3, stride=1, padding=1)
self.fc3 = nn.Linear(12 * 5 * 5, 100)
self.fc4 = nn.Linear(100, 1)
def forward(self, x):
x = self.fc1(x)
x = nn.functional.relu(x)
x = self.fc2(x)
x = nn.functional.relu(x)
x = x.view(-1, 1, 10, 10) # 将全连接层输出的一维向量转换成1x25x25的矩阵
x = self.conv1(x)
x = nn.functional.relu(x)
#x = self.pool1(x)
x = self.conv2(x)
x = nn.functional.relu(x)
x = self.conv3(x)
x = nn.functional.relu(x)
x = self.conv4(x)
x = nn.functional.relu(x)
x = self.pool4(x)
x = self.conv5(x)
x = nn.functional.relu(x)
x = self.conv6(x)
x = nn.functional.relu(x)
x = x.view(-1, 12*5*5) # 将卷积层输出的二维特征图展开成一维向量
x = self.fc3(x)
x = nn.functional.relu(x)
x = self.fc4(x)
x = x.view(-1, 1, 1) # 将全连接层输出的一维向量转换成5x5的矩阵
return x
# 定义超参数空间
parameters = {
'learning_rate': [0.00005,0.0001,0.0005, 0.001, 0.0015,0.002,0.003,0.01,0.1],
'num_epochs': [100,150, 200,250, 300],
'optimizer': ['adam', 'sgd'],
'regularization': [0.00, 0.0001, 0.001]
}
# 定义模型评估函数
def evaluate_model(model, data, labels):
predictions = model(data)
accuracy = accuracy_score(labels, predictions.argmax(dim=1))
return accuracy
# 定义CNN模型和优化器
model = CNN()
criterion = nn.CrossEntropyLoss()
# 使用网格搜索进行超参数调优
from sklearn.base import BaseEstimator
class CNNEstimator(BaseEstimator):
def __init__(self, learning_rate=0.00005,num_epochs=100,optimizer='adam',regularization=0.00):
self.model = CNN()
self.learning_rate = learning_rate
self.num_epochs = num_epochs
self.optimizer = optimizer
self.regularization = regularization
def fit(self, inputs, labels):
# 数据转换为Tensor
X = torch.Tensor(inputs)
y = torch.Tensor(labels)
# 定义优化器和损失函数
optimizer = optim.Adam(self.model.parameters(), lr=self.learning_rate)
criterion = nn.MSELoss()
# 训练循环
for epoch in range(self.num_epochs):
running_loss = 0.0
for i in range(len(inputs)):
optimizer.zero_grad()
# Get input and label data
input_data = inputs[i]
label_data = labels[i]
# Forward pass
inputs_tensor = torch.tensor(input_data, dtype=torch.float32)
outputs_tensor = self.model(inputs_tensor) # 使用self.model调用模型
# Compute loss and backward pass
labels_tensor = torch.tensor(label_data, dtype=torch.float32)
loss = criterion(outputs_tensor, labels_tensor)
loss.backward()
optimizer.step()
# Update running loss
running_loss += loss.item()
print('Epoch [{}/{}], Loss: {:.8f}'.format(epoch + 1, self.num_epochs, running_loss / len(inputs)))
def predict(self, X_test):
# 数据转换为Tensor
X = torch.Tensor(X_test)
# 前向传播
outputs = self.model(X)
# 返回预测结果
predictions = outputs.detach().numpy()
return predictions
model = CNNEstimator( learning_rate=0.00005,num_epochs=100,optimizer='adam',regularization=0.00)
grid_search = GridSearchCV(estimator=model, param_grid=parameters, scoring='accuracy', cv=3)
grid_search.fit(inputs, labels)
# 输出最佳超参数组合
print("Best Hyperparameters:", grid_search.best_params_)
# 使用最佳超参数训练最终模型
best_model = grid_search.best_estimator_
best_model.fit(inputs, labels)
# 在测试集上评估模型性能
test_accuracy = evaluate_model(best_model, X_test, y_test)
print("Test Accuracy:", test_accuracy)
torch.save(model, "my_model2.pth")
网格搜索优化的CNN
于 2023-05-10 20:30:57 首次发布