Conv1D 不更新权重。 (全为零)和测试输出总是相同的,等于最后一层权重?

Posted

技术标签:

【中文标题】Conv1D 不更新权重。 (全为零)和测试输出总是相同的,等于最后一层权重?【英文标题】:Conv1D does not update the weights. (All zero) and Test outputs are always same which is equal to Last layer Weights? 【发布时间】:2018-07-11 10:12:00 【问题描述】:

我想使用 1D CNN 来预测第二天的太阳能。时间序列数据分辨率为一小时,长度为一年。我正在用第 1 天的数据训练模型来预测第 2 天。xtrain = day1, ytrain = day2, xtest = day3 来预测 day4。

24 小时数据输入 -> CNN -> 24 小时输出

我已经对数据进行了 10 天的训练(样本);然后提前 4 天预测,问题是无论输入是什么,CNN 总是给出相同的输出值。然后,我检查了权重,只有输出层的权重是非零的。此外,输出值不会随着输入的不同而改变。

数据链接:https://mega.nz/#!NpoTzIBJ!U5l8ToQgcJ6xif2tMjIrXuace3skhrtwLEdeoWe_FkM

权重矩阵图:

预测值图表:

代码:

import pandas
from pandas import Series
from pandas import DataFrame
import keras
from keras.callbacks import ModelCheckpoint
from sklearn.metrics import r2_score
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation, regularizers, initializers
from keras.layers import Conv1D,  MaxPooling1D, Flatten, AveragePooling1D
from keras.activations import *
from keras.losses import *
from keras.optimizers import *
from keras.utils import plot_model
from keras.models import Sequential
from keras.utils import plot_model
import numpy as np
import matplotlib.pyplot as plt
from sklearn import preprocessing
from numpy import zeros, newaxis
from keras.callbacks import EarlyStopping
import sklearn.metrics
from sklearn.metrics import mean_squared_error
from math import sqrt

data = pandas.read_csv("meas.csv", header=0)
dataset = data.values[:,1]

all_pred_data = []
ytest_all = []

model = Sequential()
model.add(Conv1D(3,kernel_size=3,activation='relu', input_shape=xtrain.shape[1:3],kernel_initializer=initializers.RandomUniform(minval=-1, maxval=1),kernel_regularizer=regularizers.l2(0.1))) #input_shape=()
model.add(AveragePooling1D(pool_size=3))
model.add(Conv1D(3,kernel_size=3,activation='relu', input_shape=xtrain.shape[1:3],kernel_initializer=initializers.RandomUniform(minval=-1, maxval=1),kernel_regularizer=regularizers.l2(0.1))) #input_shape=()
model.add(AveragePooling1D(pool_size=3))
model.add(Flatten())
model.add(Dense(42,activation='tanh',kernel_regularizer=regularizers.l2(0.1),kernel_initializer=initializers.RandomUniform(minval=-1, maxval=1)))
model.add(Dense(24, activation='linear',kernel_regularizer=regularizers.l2(0.1),kernel_initializer=initializers.RandomUniform(minval=-1, maxval=1)))

model.compile(loss='mse',
          optimizer=keras.optimizers.Adam(),
          metrics=['mae','accuracy'])


for i in range(0,10-1,1): 

    xtrain = dataset[24*(i+1)-24:24*(i+1)]
    ytrain = dataset[24*(i+1):24*(i+2)]

    xtrain = xtrain.reshape(1,24,1)
    ytrain = ytrain.reshape(1,24)

    model.fit(xtrain,ytrain,epochs=500,verbose=2) 


# TEST
for i in range(20,25-1,1):
    xtest = dataset[24*(i+1):24*(i+2)] #(i+1):(i+6+1)
    ytest = dataset[24*(i+2):24*(i+2)+24]

    xtest = xtest.reshape(1,xtrain.shape[1], 1)

    pred_data = np.round(model.predict(xtest),3)

    pred_data_transpose = pred_data.transpose()

    all_pred_data.extend(pred_data_transpose)
    ytest_all.extend(np.round(ytest,3))

【问题讨论】:

【参考方案1】:

如果权重全部为 0,它们将永远不会改变,因为梯度将始终为 0,为避免这种情况,请尝试对数据进行归一化,以便更容易训练网络,如果对输入数据进行归一化,请尝试使用 batch_normalization不够

【讨论】:

数据已经标准化。 CNN 权重为零,但最后的密集层权重非零 如果 CNN 权重为零,则该层的输出将始终为零,因此后续层的输出始终相同是正常的。如果您的数据已经归一化(0 均值和 1 方差)尝试降低学习率,在每个卷积之前添加批量归一化,尝试对卷积进行不同的权重初始化,xavier(keras 中 conv 的默认初始化器)通常非常好。要查看学习率是否太大,请查看网络需要多长时间才能输出始终相同的结果,如果这种情况发生得很快,很明显你的 LR 太大了。

以上是关于Conv1D 不更新权重。 (全为零)和测试输出总是相同的,等于最后一层权重?的主要内容,如果未能解决你的问题,请参考以下文章

诚之和:Numpy怎么检查数组全为零的几种方法

检查字节数组是不是全为零的最快方法

使用 OneVsRestClassifier 时全为零

mpu6050读出来的数据全为零是怎么回事

运行 ROS 服务时,IMU 客户端响应值全为零

python浮点数,即使全为零,也保留有效数字