今天的数据集是皮马岛印第安人的糖尿病发病数据集。
参数分别代表了:
1. 怀孕次数
2. 口服葡萄糖耐量试验 2 小时后的血浆葡萄糖浓度
3. 舒张压(毫米汞柱)
4. 肱三头肌皮肤褶皱厚度(毫米)
5. 2 小时血清胰岛素(微英寸/毫升)
6. 体重指数
7. 糖尿病血统功能
8. 年龄(岁)
最后一列是第九列分别是0,1这里笔者应该能猜到这是患病与否的标致,0就是没有糖尿病,1就是有糖尿病。
跟着教程敲了一边代码:
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import tqdm
from sklearn.model_selection import StratifiedKFold
data=np.loadtxt("pima-indians-diabetes.csv",delimiter=',')
X=data[:,0:8]
y=data[:,8]
X=torch.tensor(X,dtype=torch.float32)
y=torch.tensor(y,dtype=torch.float32)
def model_train(X_train,y_train,X_test,y_test):
model=nn.Sequential(
nn.Linear(8,12),
nn.ReLU(),
nn.Linear(12,8),
nn.ReLU(),
nn.Linear(8,1),
nn.Sigmoid()
)
loss_fn=nn.BCELoss()
optimizer=optim.Adam(model.parameters(),lr=0.0001)
n_epochs=25
batch_size=10
batches_per_epoch=len(X_train)//batch_size
for epoch in range(n_epochs):
with tqdm.trange(batches_per_epoch,unit="batch",mininterval=0,disable=True) as bar:
bar.set_description(f"Epoch {epoch}")
for i in bar:
start=i*batch_size
X_batch=X_train[start:start+batch_size]
y_batch=y_train[start:start+batch_size]
y_pred=model(X_batch)
loss=loss_fn(y_pred,y_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
acc=(y_pred.round()==y_batch).float().mean()
bar.set_postfix(
loss=float(loss),
acc=float(acc)
)
y_pred=model(X_test)
acc=(y_pred.round()==y_test).float().mean()
return float(acc)
kfold=StratifiedKFold(n_splits=5,shuffle=True)
cv_scores=[]
for train,test in kfold.split(X,y):
acc=model_train(X[train],y[train],X[test],y[test])
print("Accuracy: %.2f"%acc)
cv_scores.append(acc)
print("%.2f%% (+/-) %.2f%%"%(np.mean(cv_scores)*100,np.std(cv_scores)*100))
这个代码很完整,从加载数据,数据转化,模型搭建,确定损失函数,构造优化器,指定epoch和batch_size,以及定义整个训练过程和使用tqdm来可视化训练的过程,最后还使用k交叉验证对模型进行了验证。
然后我们来run一下:
emmm,是的报错了。
先看一下第六十行:
acc=model_train(X[train],y[train],X[test],y[test])
再去看一下教程里的代码,可是也没写错,但是为啥会说我们的输入shape不一样呢
那没办法,只能来看看我们的输入的shape了,
X和y分别是对应我们的输入和预估的结果值
那就去分别打印一下这两个变量的shape来看看哦
X=torch.tensor(X,dtype=torch.float32)
y=torch.tensor(y,dtype=torch.float32)
print(X.shape)
print(y.shape)
结果:
问题就出在这里了,y的shape应该是[768,1]才对,因为每一组x都得有一个对应的y,所以这里的y如果是[768] 那么就意味着 768组x对应一个y,但是这个y却是一个一维的向量,所以我们需要把把y的shape改变一下
y=torch.tensor(y,dtype=torch.float32).reshape(-1,1)
然后再次运行:
就成功了,那么最终的代码:
import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
import tqdm
from sklearn.model_selection import StratifiedKFold
data=np.loadtxt("pima-indians-diabetes.csv",delimiter=',')
X=data[:,0:8]
y=data[:,8]
X=torch.tensor(X,dtype=torch.float32)
y=torch.tensor(y,dtype=torch.float32).reshape(-1,1)
def model_train(X_train,y_train,X_test,y_test):
model=nn.Sequential(
nn.Linear(8,12),
nn.ReLU(),
nn.Linear(12,8),
nn.ReLU(),
nn.Linear(8,1),
nn.Sigmoid()
)
loss_fn=nn.BCELoss()
optimizer=optim.Adam(model.parameters(),lr=0.0001)
n_epochs=25
batch_size=10
batches_per_epoch=len(X_train)//batch_size
for epoch in range(n_epochs):
with tqdm.trange(batches_per_epoch,unit="batch",mininterval=0,disable=True) as bar:
bar.set_description(f"Epoch {epoch}")
for i in bar:
start=i*batch_size
X_batch=X_train[start:start+batch_size]
y_batch=y_train[start:start+batch_size]
y_pred=model(X_batch)
loss=loss_fn(y_pred,y_batch)
optimizer.zero_grad()
loss.backward()
optimizer.step()
acc=(y_pred.round()==y_batch).float().mean()
bar.set_postfix(
loss=float(loss),
acc=float(acc)
)
y_pred=model(X_test)
acc=(y_pred.round()==y_test).float().mean()
return float(acc)
kfold=StratifiedKFold(n_splits=5,shuffle=True)
cv_scores=[]
for train,test in kfold.split(X,y):
acc=model_train(X[train],y[train],X[test],y[test])
print("Accuracy: %.2f"%acc)
cv_scores.append(acc)
print("%.2f%% (+/-) %.2f%%"%(np.mean(cv_scores)*100,np.std(cv_scores)*100))
完