pytorch,从数据集dataload开始网络搭建

1.数据集载入

网上许多的搭建网络的历程中都是使用已经组织好的数据集,当使用自定义的数据集需要以下操作

1.1 假设新建一个myDataset.py

from torch.utils.data import Dataset,DataLoader
import torchvision
import torch
import os
import h5py
import numpy as np
class myDataset(torch.utils.data.Dataset):#需要继承torch.utils.data.Dataset
    def __init__(self,fileset):#可以添加一些参数

        # 初始化文件路径或文件名列表。
        # 初始化该类的一些基本参数。
        '''
        例如:
        self.set=set
        self.len=np.sum(np.array( [set_num[key] for key in set_num] ))
        '''
        pass
    def __getitem__(self, index):
        #1 从文件中读取一个数据(例如,plt.imread)。
        #2 预处理数据(例如torchvision.Transform)。
        #3 返回数据对(例如图像和标签)。
        # 这里需要注意的是,第一步:read one data,是一个data
       	'''
       	例如:
       	path=root+'{}.npy'.format(index)
       	data,label=read(path)
       	return data,label
       	'''
       	pass  
    def __len__(self):
        # 返回数据集的总大小。
        '''
        例如:
        return self.len
        '''
        pass
  • 注意__getitem__返回的 data,label转化成tensor不一定是什么数据类型,很可能会在网络中tensor运算中出错,例如提示

Expected object of scalar type Long but got scalar type Float for sequence element #2

  • 可以在__getitem__就转化成指定数据类型的tensor
def __getitem__(self, index):
	'''
	
	'''
	label=torch.from_numpy(label).int()#可以是.long()  .float()
	sample=torch.from_numpy(sample)
	return sample,label

1.2 引入

在训练或者测试的文件里引入myDataset.py

from myDataset import myDataset
from torch.utils.data import Dataset,DataLoader,WeightedRandomSampler

batch_size=128
train_dataset=heartDataset()
train_loader = DataLoader(dataset=train_dataset, batch_size=batch_size)
#每次回返回batch_size个样本和数据
for index,data in enumerate(tqdm(train_loader)):
	samples,labels=data

1.3 采样策略

需要打乱训练顺序或者,样本不均衡的时候需要采用不同的策略

  • 顺序采样
from torch.utils.data import Dataset,DataLoader,WeightedRandomSampler
train_set=['a_set','b_set']
train_dataset=myDataset(fileset=train_set)
train_loader = DataLoader(dataset=train_dataset, batch_size=32, shuffle=False)
  • 随机采样
from torch.utils.data import Dataset,DataLoader,WeightedRandomSampler
train_set=['a_set','b_set']
train_dataset=heartDataset(fileset=train_set)
train_loader = DataLoader(dataset=train_dataset, batch_size=32, shuffle=True)
  • 加权采样
from torch.utils.data import Dataset,DataLoader,WeightedRandomSampler
train_set=['a_set','b_set']
train_dataset=heartDataset(fileset=train_set)
sampler=WeightedRandomSampler(samples_weight,num_samples=set_nums,replacement=True)
#replacement表示可不可以重新采
#samples_weight表示采样的权重,越大越可能采到,加起来不一定要是1,比如samples_weight=[1,2,1,3]
train_loader = DataLoader(dataset=train_dataset, batch_size=128, sampler=sampler)
  • ps: samples_weight是每一个样本的权重,不是每一个类别
  • 由于类别不均衡,想改更改每个样本的采样权重可以采用以下方式
from torch.utils.data import Dataset,DataLoader,WeightedRandomSampler
train_set=['a_set','b_set']
train_dataset=heartDataset(train_set)

train_loader = DataLoader(dataset=train_dataset, batch_size=1)

samples_weight=[]
samples_weight.extend( samples_w[label.item()]  for [_,label] in train_loader)
sampler = WeightedRandomSampler(samples_weight,num_samples=set_nums,replacement=True)

train_loader = DataLoader(dataset=train_dataset, batch_size=128, sampler=sampler)

2 搭建网络

2.1 假设新建一个myModel.py

import torch
import torchvision
import torchvision.transforms as transforms
import torch.nn as nn

class Net(nn.Module):
    def __init__(self):
        super(Net1, self).__init__()
        self.conv1=nn.Sequential(
         #
        )
        self.conv2=nn.Sequential(
         #
        )
        self.mpl3=nn.Sequential(
         #
        )
       self.out4=nn.Sequential(
         #
        )
   def forward(self,x):
        #卷积提特征
        x=self.conv1(x)
        x=self.conv2(x)
        #过度全连接层
        x=x.flatten(start_dim=1)#阻止批次扁平化
		#全连接层分类
        x=self.mpl3(x)
        x=self.out4(x)

        return x

Sequential可以添加一些序列操作

#例如
self.conv1=nn.Sequential(
            nn.Conv2d(in_channels=64,out_channels=128,kernel_size=5),
            nn.BatchNorm1d(128),
            nn.ReLU(),
            nn.MaxPool1d(kernel_size=2),
        )

2.2 训练

在训练或者测试的文件里引入myModel.py

import torchvision
import torch
import torch.optim as optim
import torch.nn as nn
from tqdm import tqdm
from myModel import Net

gpu_id=0
epoches=10
root='/data'
train_set=[<setname>,<setname>]


try:
    if torch.cuda.is_available():
        device = torch.device('cuda:{}'.format(gpu_id))
    else:
        device = torch.device('cpu')
    print("device{ }".format(device))
except:
    device = torch.device('cpu')
#载入数据
train_dataset=heartDataset(tarin_set)
train_loader = DataLoader(dataset=test_dataset, batch_size=32, shuffle=False)

model=Net().to(device)
optimizer = optim.Adam(model.parameters(),weight_decay=0.01)#weight_decay=0.01引入正则化
criterion = nn.BCELoss()#设置损失函数


for epoch in range(epoches):
	print("ecpoch:{}/{}".format(epoch+1,epoches))
	for index,data in enumerate(tqdm(train_loader)):
		samples,labels=data
		labels = Variable(labels.float()).to(device)#根据网络或者报错更改数据类型
	    samples =Variable(samples.float()).to(device)
	
		optimizer.zero_grad()
		
		output=model(samples)
		loss = criterion(output, labels)
		loss.backward()
		
		optimizer.step()

savepath=root+'/model'+'/m_e{}'.format(epoches)+'.pt'
torch.save(model.state_dict(), savepath)	

2.3测试

即使没有backward,输入也会对模型的参数造成影响,作为测试需要使用:

  • 1 设置model.eval(),和model.train()主要是BNDropout的差别

with torch.no_grad():下输入主要是为了不计算梯度,减少gpu内存消耗,不能更新权值

loadpath=root+'/model'+'/m_e{}'.format(epoches)+'.pt'
model=Net()
model.load_state_dict(torch.load(loadpath, map_location=device if device =='cpu' else "{}".format(device)))

model.eval()

for index,data in  enumerate(tqdm(test_loader)):
    samples,labels,names=data
    labels = labels.float().to(device)
    samples = samples.float().to(device)
    with torch.no_grad():
    	output=model(samples)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是一个使用PyTorch搭建NARX网络的示例: ```python import torch import torch.nn as nn import numpy as np import matplotlib.pyplot as plt from sklearn.metrics import mean_squared_error # 加载数据 data = np.load('sunspot.npy') train_ratio = 0.7 train_size = int(train_ratio * len(data)) train_data = data[:train_size] test_data = data[train_size:] # 定义NARX模型 class NARX(nn.Module): def __init__(self): super(NARX, self).__init__() self.lstm = nn.LSTM(1, 100, batch_first=True) self.linear = nn.Linear(100, 1) def forward(self, x): x, _ = self.lstm(x) x = self.linear(x[:, -1, :]) return x model = NARX() criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # 训练模型 X_train, y_train = [], [] for i in range(2, len(train_data)): X_train.append([[train_data[i-2]], [train_data[i-1]]]) y_train.append(train_data[i]) X_train, y_train = torch.tensor(X_train).float(), torch.tensor(y_train).float() for epoch in range(50): optimizer.zero_grad() y_pred = model(X_train) loss = criterion(y_pred, y_train) loss.backward() optimizer.step() # 测试模型 X_test, y_test = [], [] for i in range(2, len(test_data)): X_test.append([[test_data[i-2]], [test_data[i-1]]]) y_test.append(test_data[i]) X_test, y_test = torch.tensor(X_test).float(), torch.tensor(y_test).float() y_pred = model(X_test).detach().numpy() # 绘制预测结果 plt.plot(y_test, label='Actual') plt.plot(y_pred, label='Predicted') plt.legend() plt.xlabel('Month') plt.ylabel('Sunspot Number') plt.title('Sunspot Number Prediction using NARX') plt.show() # 计算均方误差 mse = mean_squared_error(y_test, y_pred) print('Mean Squared Error:', mse) ``` 在这个示例中,我们使用PyTorch搭建了一个NARX模型。我们使用LSTM层来处理序列数据,并使用线性层来实现NARX结构。我们使用太阳黑子数据集来训练和测试模型,并绘制了预测结果。最后,我们计算了测试集上的均方误差。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值