Pytorch全连接网络:激活函数对一维拟合问题的影响探讨;网络加深后带来的loss不降问题

Posted 无知的吱屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pytorch全连接网络:激活函数对一维拟合问题的影响探讨;网络加深后带来的loss不降问题相关的知识,希望对你有一定的参考价值。

    一、简单讨论激活函数对拟合问题的影响

       最近在学习全连接网络,希望利用全连接网络实现拟合或者插值问题。即给定一些已知的散点,想要利用全连接网络,输入一个x,相应地网络会输出一个y,利用已知散点的真实值计算MSELoss,从而逼近已知点。

网络的结构很简单,利用了两层线性层,中间加不同的激活函数(代码显示的是ReLU):

class DNN(nn.Module):
    def __init__(self):
        super().__init__()
        layers =  [1,50,1]
        self.layer1 = nn.Linear(layers[0],layers[1])
        self.layer2 = nn.Linear(layers[1],layers[2])
        self.relu = nn.ReLU()
    def forward(self,d):
        d1 = self.layer1(d)
        d1 = self.relu(d1)
        d2 = self.layer2(d1)
        return d2

我用的例子是sin(x),在-π到π的50个点中随机取10个,作为我们的训练数据[x,y]:

x = np.linspace(-np.pi,np.pi).astype(np.float32)
y = np.sin(x)
#随机取十个点
x_train = random.sample(x.tolist(),10)
y_train = np.sin(x_train)
plt.scatter(x_train,y_train,c="r")
plt.plot(x,y)

随机点的位置如下:

设定一些参数,比如迭代10000次,学习率调成0.1等,每次只从训练数据中输入一个。以下是不同激活函数的训练结果:

从以上结果我们可以得到一些不太准确的粗略讨论

(1)不同的激活函数对输出的影响是不同的。

(2)LeakyReLU我不确定为什么会出现右边界严重脱离的情况,对结果影响比较严重。

(3)就平滑度而言,直观感受是ELU和Sigmoid会更加平滑,Tanh会出现尖灭点,这和数据点位置也有一定的关系。而ReLU整体直线的拼接感会比较重。

 (4)就拟合程度而言,不论是哪一种激活函数,都没有办法保证已知点很好地落在预测曲线上,增加神经元的个数或许会有更好的效果。就这点而言,Tanh表现要更好一点。

二、网络加深的问题

       以上是对于两层简单网络不同激活函数的探讨,接下来我想聊聊把网络加深对结果带来的影响。我们知道,如果是拟合问题,我们希望预测出来的整体曲线是平滑且符合大致趋势的,但是如果是插值问题,我们更希望看到已知的数据点是在我们预测的曲线上面的,由于loss几乎不可能完全为0,所以我们想要尽可能地让它收敛,哪怕是达到过拟合的情况。 

于是我把网络该成立四层的全连接,中间用不同的激活函数进行非线性映射:

class DNN(nn.Module):
    def __init__(self):
        super().__init__()
        layers =  [1,50,25,12,1]
        self.layer1 = nn.Linear(layers[0],layers[1])
        self.layer2 = nn.Linear(layers[1],layers[2])
        self.layer3 = nn.Linear(layers[2],layers[3])
        self.layer4 = nn.Linear(layers[3],layers[4])
        self.elu = nn.ELU()
    def forward(self,d):
        d1 = self.elu(self.layer1(d ))
        d2 = self.elu(self.layer2(d1))
        d3 = self.elu(self.layer3(d2))
        d4 = self.layer4(d3)

        return d4

结果如下:

       可以看到,不论是哪个激活函数,预测出来的曲线都完全不对,训练过程中loss也基本不变,但是神经元的权重是在改变的。这显然已经不是激活函数的问题了,而且可以看出,在0的左右两端不论输入是什么,出来的值基本上是一致的。这一直是我很疑惑的点,有可能是因为神经元过多,而输入数据仅有一个x导致的。

       但当我以为只是每一层的神经元过多,我把每一层的神经元减少,并用ReLU和Tanh作为激活函数时,结果却依旧如此,甚至变得更加糟糕。

每一层的神经元:

 layers =  [1,12,6,3,1]

希望大佬们可以提出一些可能出现的原因!!!

以上是关于Pytorch全连接网络:激活函数对一维拟合问题的影响探讨;网络加深后带来的loss不降问题的主要内容,如果未能解决你的问题,请参考以下文章

深度学习常见概念字典(感知机全连接层激活函数损失函数反向传播过拟合等)

深度学习常见概念字典(感知机全连接层激活函数损失函数反向传播过拟合等)

PyTorch搭建全连接网络训练MNIST数据集分类任务和气温预测回归任务及全连接网络过拟合和欠拟合的调参方式

pytorch Alexnet 网络模型搭建

PyTorch如何实现多层全连接神经网络

动手学习pytorch——多层感知机