3.1. 神经网络基础
3.1.1 神经元(Neuron)
就像形成大脑基本元素的神经元一样,神经元是构成神经网络的基本结构。想象一下,当大脑得到新信息时如何处理。当大脑获得信息时,一般会处理它并生成一个输出。类似地,在神经网络中,神经元接收输入,处理它并产生输出,而这个输出被发送到其它神经元做进一步处理,或者作为最终结果进行输出。如图3-1:
图3-1
3.1.2 权重(Weights)
当输入进入神经元时,它会乘以一个权重。例如,一个神经元有两个输入,则每个输入将具有分配给它的一个权重。初始化是随机分配权重,并在模型训练过程中,利用反向传播更新这些权重。训练后的神经网络对其输入赋予较高的权重,则认为相比而言是更为重要的输入。为零的权重则表示特定的特征是微不足道的。
假设输入为X1,并且与其相关联的权重为 W1,那么在通过节点之后,输入变为X1 *W1。
3.1.3 偏差(Bias)
除了权重之外,另一个被应用于输入的线性分量被称为偏差。它被加到权重与输入相乘的结果中。基本上添加偏差的目的是来改变权重与输入相乘所得结果的范围。添加偏差后,结果将看起来更加接近真实值,这是输入变换的最终线性分量。
3.1.4 激活函数(Activation Function)
一旦将线性分量应用于输入,将会需要一个非线性函数,将神经元的特征保留并进行映射。激活函数将输入信号转换为输出信号。应用激活函数后的输出看起来像 f(a *W1+ b),其中 f()就是激活函数。
在下图中,将"n"个输入给定为 X1 到 Xn 而与其相应的权重为 Wk1 到 Wkn。有一个给定值为 bk 的偏差。权重首先乘以与其对应的输入,然后与偏差加在一起。而这个值叫做 u。
U =ΣW*X +b
激活函数被应用于 u,即 f(u),并且会从神经元接收最终输出,如 yk = f(u)。
常用的激活函数:最常用的激活函数就是 Sigmoid,ReLU 和 softmax
(a)Sigmoid——最常用的激活函数之一是 Sigmoid,它被定义为:
sigmoid(x)=1/(1+e -x )
Sigmoid 变换产生一个值为 0 到 1 之间更平滑的范围。可以观察到输入值略有变化时输出值中发生的变化。
(b)ReLU(整流线性单位)——与 Sigmoid 函数不同的是,最近的网络更喜欢使用 ReLu 激活函数来处理隐藏层。该函数定义为:
f(x)=max(x,0)
当 X>0 时,函数的输出值为 X;当 X
使用 ReLU 函数的最主要的好处是对于大于 0 的所有输入来说,它都有一个不变的导数值。常数导数值有助于网络训练进行得更快。
(c) Softmax——Softmax 激活函数通常用于输出层,用于分类问题。它与 sigmoid 函数是很类似的,唯一的区别就是输出被归一化为总和为 1。在一个多类分类问题中,softmax 函数为每个类分配值,这个值可以理解为概率。
3.1.4 神经网络(Neural Network)
神经网络构成了深度学习的核心,神经网络的目标是找到一个未知函数的近似值,它由相互连接的神经元形成。这些神经元具有权重和在网络训练期间根据错误来进行更新的偏差。激活函数将非线性变换置于线性组合,而这个线性组合稍后会生成输出。
3.1.5 输入/输出/隐藏层(Input / Output / Hidden Layer)
正如它们名字所代表的那样,输入层是接收输入那一层,本质上是网络的第一层。而输出层是生成输出的那一层,也可以说是网络的最终层。处理层是网络中的隐藏层,这些隐藏层是对传入数据执行特定处理并将其生成的输出传递到下一层。输入和输出层是可见的,而中间层则是隐藏的。
3.1.6 多层感知器(MLP)
单个神经元将无法执行高度复杂的任务。因此,使用堆叠的神经元来生成所需要的输出。在最简单的网络中,有一个输入层、一个隐藏层和一个输出层。每个层都有多个神经元,并且每个层中的所有神经元都连接到下一层的所有神经元。这些网络也可以被称为完全连接的网络。
各层的神经元数量的选择是一个试错的过程。通常情况下输入层的神经元数量与输入数据的纬度相同。输出层神经元的数量,在回归问题和二元分类中通常为一个神经元,在多分类问题中通常与分类的类别数相同。隐藏层的神经元数量可以自由设定,通过试错来找到一个最合适的值,这通常是由通过网络的信息量决定的。在通常情况下,分类问题的隐藏层的神经元数量可以设定为类别数量的5-10倍,回归问题的隐藏层的神经元数量可以设定为输入数据维度的2-3倍。
3.1.7 正向传播(Forward Propagation)
正向传播是指输入通过隐藏层到输出层的运动。在正向传播中,信息沿着一个单一方向前进。输入层将输入提供给隐藏层,然后生成输出。这过程中是没有反向运动的。
3.1.8 成本函数(Cost Function)
当建立一个神经网络时,为了尽可能的将输出预测的接近实际值,通常使用成本或损失函数来衡量网络的准确性,在发生错误时也利用成本或损失函数来惩罚网络。
运行网络时的目标是提高预测精度并减少误差,从而最大限度地降低成本。最优化的输出是那些成本或损失函数值最小的输出。
3.1.9梯度下降(Gradient Descent)
梯度下降是一种最小化成本的优化算法。要直观地想一想,在爬山的时候,应该会采取小步骤,一步一步走下来,而不是一下子跳下来。因此,如果从一个点 x 开始,向下移动一点Δh,那么位置更新为 x-Δh,继续保持下降,直到达到底部。
在数学上,为了找到函数的局部最小值,通常采取与函数梯度的负数成比例的步长。
3.1.10 学习率(Learning Rate)
学习率被定义为每次迭代中成本函数中最小化的量。简单来说,下降到成本函数的最小值的速率是学习率。应该非常谨慎地选择学习率,因为它不应该是非常大的,以至于最佳解决方案被错过,也不应该非常小,以至于网络需要融合。
3.1.11 反向传播(Backpropagation)
定义神经网络时,为节点分配随机权重和偏差值。一旦收到单次迭代的输出,就可以计算出网络的错误。然后将该错误与成本函数的梯度一起反馈给网络以更新网络的权重。以便减少后续迭代中的错误。使用成本函数的梯度对权重的更新被称为反向传播。
在反向传播中,网络的运动是向后的,错误随着梯度从外层通过隐藏层流回,权重被更新。
3.1.12 批次(Batches)
在训练神经网络时,不用一次发送整个输入,将输入分成几个随机大小相等的块。与整个数据集一次性输入到网络时建立的模型相比,批量训练数据使得模型更加广义化。
3.1.13 周期(Epochs)
周期被定义为向前和向后传播中所有批次的1次训练迭代。这意味着 1 个周期是整个输入数据的单次向前和向后传递。
更多的周期将显示出更高的网络准确性,然而,网络融合也需要更长的时间。另外,需要注意的是,如果周期数太高,网络可能会过度拟合。
3.1.14 丢弃(Dropout)
Dropout 是一种正则化技术,可防止网络过度拟合。顾名思义,在训练期间,隐藏层中的一定数量的神经元被随机丢弃。这意味着训练发生在神经网络的不同组合的神经网络架构上,然后将多个网络的输出用于产生最终输出,增加了网络的泛化能力。
3.1.14 多层感知器示例——鸢尾花分类
鸢尾花数据集是机器学习中经典的数据集之一,这个数据集有4个输入维度和一个分类结果。所有的输入项目具有相同的尺度,并且都是数值型的,这个数据集被很好的研究过,不仅可以作为机器学习的数据集使用,也可以用来验证深度学习的模型。在这里将会通过这个数据集来验证一下多层感知器模型,因为这个数据集被很好的研究过,期待多层感知器可以达到95%以上的准确度。
在这个例子中,数据将会从scikit-learn提供的数据集中导入,然后将输出结果进行one-hot编码已使用神经网络的输出。在这里将构建一个具有4个神经元的输入层,和2层隐藏层,及一个输出层的神经网络。输出层采用softmax作为激化函数,使用梯度下降作为优化器。因为数据总共只有150条纪录,因此训练数据集与评估数据集采用相同的数据,都使用整个数据集。代码如下:
fromsklearn.datasetsimportload_iris
fromtorchimportnn
fromtorch.autogradimportVariable
fromtorchimportoptim
fromtorch.utils.dataimportDataLoader, TensorDataset
fromsklearn.preprocessingimportOneHotEncoder
importnumpyasnp
importtorch
epochs =150
batch_size =150
seed =7
lr =0.01
momentum =0.9
classLogisticLinear(nn.Module):
# definethe model for iris flower dataset
def__init__(self):
super(LogisticLinear,self).__init__()
self.linear = nn.Sequential()
self.linear.add_module('input', nn.Linear(4,4))
self.linear.add_module('hidden1', nn.Linear(4,6))
self.linear.add_module('hidden2', nn.Linear(6,3))
self.softmax = nn.Softmax()
defforward(self,x):
out = self.linear(x)
out = self.softmax(out)
returnout
defcreateTensorDataset(x, y):
# convertdata to Tensors
x = torch.FloatTensor(x)
y = np.reshape(y, (y.shape[],1))
# one hotencodering
enc =OneHotEncoder(sparse=False, n_values=3)
y = enc.fit_transform(y).astype('float32')
y = torch.from_numpy(y)
dataset = TensorDataset(data_tensor=x,target_tensor=y)
returndataset
if__name__ =='__main__':
# loaddata for iris flower dataset
x, y =load_iris(return_X_y=True)
labels = y
# setrandom seed
np.random.seed(seed=seed)
# createmodel
model = LogisticLinear()
# definethe loss function and optimizer
criterion = nn.BCELoss()
optimizer =optim.SGD(params=model.parameters(), lr=lr, momentum=momentum)
dataset = createTensorDataset(x, y)
dataloader =DataLoader(dataset=dataset, batch_size=batch_size)
#training the model
forepochinrange(epochs):
for(data,label)indataloader:
#convert to variable
data =Variable(data)
label = Variable(label)
#forward pass
output = model(data)
#calculate the loss
loss =criterion(output, label)
loss_data = loss.data[]
#reset gradients
optimizer.zero_grad()
#backward pass
loss.backward()
optimizer.step()
#print loss
print('{}/{} loss: {:.6f}'.format(epoch, epochs,loss_data))
model.eval()
x = torch.FloatTensor(x)
x = Variable(x)
outputs = model(x)
outputs = outputs.data.numpy()
testacc =
foroutput, labelinzip(outputs,labels):
predict = np.argmax(output)
correct_num = (predict ==label).sum()
testacc += correct_num.data[]
print("accuary:{:.2f}%".format((testacc / len(labels)) *100))
执行后,准确率达到了97%以上,虽然是一个非常简单的多层感知器,但是准确度却非常高。
3.2 卷积神经网络(CNN)
卷积神经网络主要应用于计算机视觉。假设有一个输入的大小(28,28,3)的图像,如果使用正常的神经网络,将有2352(28*28*3)个参数。并且随着图像大小的增加,参数的数量将会变得非常大,“卷积”图像能够有效的减少参数的数量(如上面滤波器定义所示)。
3.2.1 滤波器(Filters)
卷积神经网络中的滤波器与加权矩阵一样,它与输入图像的一部分相乘以产生一个回旋输出。假设有一个大小为28x28的图像,随机分配一个大小为3x3的滤波器,然后与图像不同的 3x3 部分相乘,形成所谓的卷积输出。滤波器尺寸通常小于原始图像尺寸,通常设定为3x3或者5x5的大小。
参考一下下图,这里 filter 是一个3x3矩阵,如图3-2:
图3-2
与图像的每个3x3的部分相乘以形成卷积特征图,如图3-3:
图3-3
3.2.2 池化层(Pooling)
在卷积层之间定期引入池层,是为了减少一些参数,并防止过度拟合。最常见的池化类型是使用 MAX 操作的滤波器尺寸(2,2)的池层,它使用原始图像的每个 4x4 矩阵中最大值,作为输出,有效的减少输出参数。如图3-4:
图3-4
此外,也可以使用其他操作(如平均池)进行池化,但是最大池在实践中表现更好。
3.2.3 填充(Padding)
填充是指在图像之间添加额外的零层,以使输出图像的大小与输入相同,这被称为相同的填充。在应用滤波器之后,在相同填充的情况下,卷积层具有与于实际图像相同的大小。有效填充是指将图像保持与实际图像相同的像素数量。在这种情况下,在应用滤波器之后,输出的长度和宽度的大小在每个卷积层处不断减小,输出与原始图像相同的向量。
3.2.4 数据增强(Data Augmentation)
数据增强是指从给定数据生产新数据,这被证明对预测有益。例如,如果光线变亮,可能更容易在较暗的图像中看到猫。或者,数字识别中的 9 可能会稍微倾斜或旋转,在这种情况下,旋转将解决问题并提高模型的准确性。通过旋转或增亮,可以提高数据的质量,这被称为数据增强。
3.2.4 卷积神经网络示例——医疗影像识别
目前在医疗领域,大量的采用机器学习来辅助医生进行疾病诊断,在这里通过一个医疗影像识别的例子来介绍一下卷积神经网络在图像识别领域的应用。在这里将对Kaggle上的“糖尿病视网膜病变检测“竞赛中的图像数据集进行分析(https://www.kaggle.com/c/diabetic-retinopathy-detection)。因为这个数据集中的数据量比较大,在这里仅使用其中的一部分数据来进行研究。
目前在卷积神经网络方面,发表的论文比较多,比较知名的模型有LeNet,AlexNet,VGGNet,GoogLeNet,ResNext。在这里选择google的GoogLeNet来研究这个图像数据集。GoogLeNet模型是Google在2014年提出的,其主要特征是,创新性的提出了Inception模块,并且整个网络中没有全联接层。Inception模块设计了一个局部的网络拓扑结构,然后将这些模块堆叠到一起形成一个抽象的网络结构。具体的来说就是并行的使用具有不同感受野的滤波器对输入进行卷积和池化操作,最后将输出结果按照深度拼接到一起形成输出层。代码如下:
fromtorchimportnn
fromtorch.nnimportfunctionalasF
fromtorch.autogradimportVariable
fromtorchimportoptim
importtorch
fromtorchvisionimporttransforms
fromtorch.utils.dataimportDataset, DataLoader
fromPILimportImage
train_labels ='train_labels.csv'
test_labels ='test_labels.csv'
img_folder ='train'
batch_size =64
epochs =200
lr =0.01
classBasicConv2d(nn.Module):
def__init__(self, in_channels, out_channels, **kwargs):
super(BasicConv2d,self).__init__()
self.conv = nn.Conv2d(in_channels, out_channels,bias=False, **kwargs)
self.bn = nn.BatchNorm2d(out_channels,eps=0.001)
defforward(self, x):
out =self.conv(x)
out =self.bn(out)
returnF.relu(out,inplace=True)
classInception(nn.Module):
def__init__(self, in_channels, pool_features):
super(Inception,self).__init__()
self.branch1x1 = BasicConv2d(in_channels,64,kernel_size=1)
self.branch5x5_1 = BasicConv2d(in_channels,48,kernel_size=1)
self.branch5x5_2 = BasicConv2d(48,64,kernel_size=5,padding=2)
self.branch3x3_1 = BasicConv2d(in_channels,64,kernel_size=1)
self.branch3x3_2 = BasicConv2d(64,96,kernel_size=3,padding=1)
self.branch3x3_3 = BasicConv2d(96,96,kernel_size=3,padding=1)
self.branch_pool = BasicConv2d(in_channels, pool_features,kernel_size=1)
defforward(self, x):
branch1x1 =self.branch1x1(x)
branch5x5 =self.branch5x5_1(x)
branch5x5 =self.branch5x5_2(branch5x5)
branch3x3 =self.branch3x3_1(x)
branch3x3 =self.branch3x3_2(branch3x3)
branch3x3 =self.branch3x3_3(branch3x3)
branch_pool = F.avg_pool2d(x,kernel_size=3,stride=1,padding=1)
branch_pool =self.branch_pool(branch_pool)
outputs = [branch1x1, branch5x5, branch3x3, branch_pool]
returntorch.cat(outputs)
defdefault_loader(path):
returnImage.open(path).convert('RGB')
classMyDataset(Dataset):
def__init__(self, label_file, img_folder, transform=None, target_transform=None, loader=default_loader):
imgs = []
withopen(label_file,'r')asfh:
lines = fh.readlines()
forlineinlines:
line = line.strip('\n')
line = line.rstrip()
words = line.split(',')
img = img_folder +'/'+ words[]
label =int(words[1])
imgs.append((img, label))
self.imgs = imgs
self.transform = transform
self.target_transform = target_transform
self.loader = loader
def__getitem__(self, index):
fn, label =self.imgs[index]
img =self.loader(fn)
ifself.transformis not None:
img =self.transform(img)
returnimg,label
def__len__(self):
returnlen(self.imgs)
if__name__ =='__main__':
# 像素为3x2304x3456
train_dataset = MyDataset(label_file=train_labels,img_folder=img_folder,transform=transforms.ToTensor())
test_dataset = MyDataset(label_file=train_labels,img_folder=img_folder,transform=transforms.ToTensor())
train_loader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)
test_loader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=True)
model = Inception(in_channels=3,pool_features=5)
# 定义损失函数
criterion = nn.CrossEntropyLoss(size_average=False)
# 定义优化器(梯度下降)
optimizer = optim.SGD(model.parameters(),lr=lr)
# 训练模型
foriinrange(epochs):
running_loss =0.0
running_acc =0.0
for(img, label)intrain_loader:
iftorch.cuda.is_available():
# 如果使用GPU
img = Variable(img).cuda()
label = Variable(label).cuda()
else:
# 如果使用CPU
img = Variable(img).cpu()
label = Variable(label).cpu()
# 归零操作
optimizer.zero_grad()
output = model(img)
loss = criterion(output, label)
# 反向传播
loss.backward()
optimizer.step()
running_loss += loss.data[]
_, predict = torch.max(output,1)
correct_num = (predict == label).sum()
running_acc += correct_num.data[]
running_loss /=len(train_dataset)
running_acc /=len(train_dataset)
print('[%d/%d] Loss: %.5f, Acc: %.2f'% (i +1, epochs, running_loss, running_acc *100))
# 评估模型
model.eval()
testloss =0.0
testacc =0.1
for(img, label)intest_loader:
iftorch.cuda.is_available():
# 如果使用GPU
img = Variable(img).cuda()
label = Variable(label).cuda()
else:
# 如果使用CPU
img = Variable(img).cpu()
label = Variable(label).cpu()
output = model(img)
loss = criterion(output, label)
_, predict = torch.max(output,1)
correct_num = (predict == label).sum()
testacc += correct_num.data[]
testloss /=len(test_dataset)
testacc /=len(test_dataset)
print('Loss: %.5f, Acc: %.2f'% (testloss, testacc *100))
3.3 循环神经网络(RNN)
循环神经网络特别适用于顺序数据,其中先前的输出用于预测下一个输出,在这种情况下,网络中有循环。隐藏神经元内的循环使他们能够存储有关前一个单元的信息一段时间,以便能够预测输出。隐藏层的输出在 t 时间戳内再次反馈到隐藏层。如图3-5:
图3-5
只有在完成所有的时间戳后,循环神经元的输出才能进入下一层。发送的输出更广泛,以前的信息保留的时间也较长。然后根据展开的网络将错误反向传播以更新权重。这被称为通过时间的反向传播(BPTT)。
3.3.1 循环神经元(Recurrent Neuron)
循环神经元是在 T 时间内将神经元的输出反馈自身(如图A-5),输出将返回输入 t 次。展开的神经元看起来像连接在一起的 t 个不同的神经元,这个神经元的基本优点是它给出了更广义的输出。
3.3.2 梯度消失问题(Vanishing Gradient Problem)
激活函数的梯度非常小的情况下会出现消失梯度问题。在权重乘以这些低梯度时的反向传播过程中,它们往往变得非常小,并且随着网络进一步深入而"消失"。
这使得神经网络忘记了长距离依赖。这对循环神经网络来说是一个问题,长期依赖对循环神经网络来说是非常重要的。这可以通过使用不具有小梯度的激活函数 ReLu 来解决。
3.3.3 梯度爆炸问题(Exploding Gradient Problem)
这与梯度消失问题完全相反,激活函数的梯度过大。在反向传播期间,它使特定节点的权重相对于其他节点的权重非常高,这使得它们不重要。这可以通过剪切梯度来轻松解决,使其不超过一定值。
3.3.4 循环神经网络示例——空气质量预测
在实际生活中,有很多的预测分析都是基于时间序列的,例如:销售额的预测、旅行者的人数、股票价格走势、空气质量预测、机器翻译、情感分析等。在这里通过空气质量预测来介绍一下循环神经网络的应用。
这个数据集是美国驻华(北京)大使馆五年内报告的天气和污染水平。数据集中包含日期,PM2.5污染物浓度,以及天气信息、包括露点(露点温度)、温度、压力、风向、风速、累计的降雪小时数和累积的降水小时数。数据集中的数据保护从2010年1月1号到2014年12月31号的数据。数据集可以到UCI机器学习仓库网站下载(http://archive.ics.uci.edu/ml/datasets/Beijing+PM2.5+Data)。
数据集下载后,查看数据集的内容发现,PM2.5的数值有不存在的现象,在这里将把这些空值数据直接删除。No列,没有实际的作用,将直接删除。日期时按照年月日以及小时分割的,在这里需要将其合并为一个时间值,并其设置为DataFrame的索引。数据集中只有风向是分类变量外,其他的都是数值变量,因为数据的尺度不一样,对数据进行归一元处理,并对风向进行one-hot编码。数据处理完成后,将数据分成训练集和评估集,使用训练集训练一个简单的LSTM模型,并使用模型来预测评估集的结果,通过图表展示通过模型预测的结构与评估集的实际结果进行对比,代码如下:
fromtorchimportnn
fromtorch.autogradimportVariable
fromtorchimportoptim
fromtorch.utils.dataimportDataLoader, TensorDataset
importnumpyasnp
importtorch
frompandasimportread_csv, get_dummies, concat, DataFrame
fromdatetimeimportdatetime
fromsklearn.preprocessingimportMinMaxScaler
frommatplotlibimportpyplotasplt
filename ='pollution_original.csv'
time_step =24
batch_size =120
epochs =50
lr =0.01
feature =11
train_len =41000
# combine the datetime
defprase(x):
returndatetime.strptime(x,'%Y %m %d %H')
defget_dataset():
dataset = read_csv(filename,parse_dates=[['year','month','day','hour']],index_col=,date_parser=prase)
dataset.drop('No',axis=1,inplace=True)
# set thecolumn name
dataset.columns = ['pollution','dew','temp','press','wnd_dir','wnd_spd','snow','rain']
dataset.index.name ='date'
# one hot encode
df = get_dummies(dataset['wnd_dir'])
dataset = concat((dataset, df),axis=1)
dataset.drop('wnd_dir',axis=1,inplace=True)
dataset.dropna(inplace=True)
scaler = MinMaxScaler()
dataset =scaler.fit_transform(dataset)
returndataset
defmake_dataset(data, n_input=1, out_index=,dropnan=True):
n_vars =1iftype(data)islistelsedata.shape[1]
df = DataFrame(data)
cols, names = [], []
# input(t-n, ... t-1)
foriinrange(n_input,, -1):
cols.append(df.shift(i))
names += [('var%d(t-%d)'% (j +1,i))forjinrange(n_vars)]
# output(t)
cols.append(df[df.columns[out_index]])
names += ['result']
# combinethe inputs
result = concat(cols,axis=1)
result.columns = names
# delmiss values cols
ifdropnan:
result.dropna(inplace=True)
returnresult
defcreateTensorDataset(data):
values = data.values
x = values[:, : values.shape[1] -1]
y = values[:, values.shape[1] -1]
# convertdata to Tensors
x = torch.FloatTensor(x)
y = np.reshape(y, (y.shape[],1)).astype('float32')
y = torch.from_numpy(y)
# createTensor Dataset
dataset = TensorDataset(data_tensor=x,target_tensor=y)
returndataset
classLSTMPollution(nn.Module):
def__init__(self):
super(LSTMPollution,self).__init__()
#define the model
self.lstms1 = nn.LSTM(input_size=(feature* time_step),hidden_size=33,num_layers=5)
self.linear1= nn.Linear(in_features=33,out_features=1)
defforward(self, x):
out, _ =self.lstms1(x)
# b,s, h = out.size()
out = out[:, -1]
out =self.linear1(out)
returnout
if__name__ =='__main__':
np.random.seed(7)
# readdata from csv
data = get_dataset()
# createdataset for lstm
dataset =make_dataset(data,n_input=time_step)
train_set = dataset[:train_len]
test_set = dataset[train_len:len(dataset)]
# createTensor Dataset
train_set =createTensorDataset(train_set)
model = LSTMPollution()
# definethe loss function and optimizer
criterion = nn.MSELoss()
optimizer = optim.Adam(params=model.parameters(),lr=lr)
dataloader = DataLoader(dataset=train_set,batch_size=batch_size)
#training the model
forepochinrange(epochs):
losses = []
for(data,label)indataloader:
#convert to variable
data =Variable(data)
label = Variable(label)
#forward pass
output =model(data)
#calculate the loss
loss =criterion(output, label)
loss_data = loss.data[]
losses.append(loss_data)
#reset gradients
optimizer.zero_grad()
#backward pass
loss.backward()
optimizer.step()
#print loss
print('epoch {}/{} loss:{:.6f}'.format(epoch +1, epochs,np.mean(losses)))
#evaluate new data
model.eval()
# createTensor Dataset
test_set =createTensorDataset(test_set)
x = Variable(test_set.data_tensor)
y = test_set.target_tensor.numpy()
outputs = model(x)
outputs = outputs.data.numpy()
# createplot to show the predict result
plt.plot(y,color='blue',label='Actual')
plt.plot(outputs,color='green',label='Prediction')
plt.legend(loc='upper right')
plt.show()
代码的执行结果,模型对评估集的预测结果与评估集的实际结果对比如图3-6:
图3-6
本文来自企鹅号 - 知之Python媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文来自企鹅号 - 知之Python媒体
如有侵权,请联系 cloudcommunity@tencent.com 删除。