[Tensorflow2.0 keras]初始化(自定义)网络层参数

一、背景

二、初始化网络层参数
1. 思路

其实没有什么思路,因为keras中内置了初始化参数的接口
使用:

layers.Dense(...,kernel_initializer,bias_initializer,...)

中的kernel_initializerbias_initializer初始化Dense神经网络层中的参数,其中kernel_initializer初始化参数w,bias_initializer初始化参数b,变量类型为tensorflow.python.keras.initializers.*,例如tf.keras.initializers.ones()或者tf.keras.initializers.constant([2.0])

2.代码示例

下面给出一个拟合方程y=x+2的只含有一层全连接层的神经网络进行示范说明。
对于该网络,训练数据为一个实数x和对应的y, 其中y=x+2。
代码如下:

import tensorflow as tf
import numpy as np
from tensorflow.keras import layers
import pandas as pd
# 使用网络方式实现一个网络拟合一次函数 y = a*x+b,其中 a = 1, b= 2
# 构建网络
def buildModel():
	# 只有一层全连接层,存在两个参数w和b,并使用kernel_initializer初始化w参数为1.0
	# 使用bias_initializer参数为2.0
    model = tf.keras.Sequential([
        layers.Dense(1, kernel_initializer=tf.keras.initializers.ones(),
                     bias_initializer=tf.keras.initializers.constant([2.0]))
    ])
    # 定义优化器
    optimizer = tf.keras.optimizers.RMSprop(0.001)
    # 编译优化器
    model.compile(loss='mse',
                  optimizer=optimizer,
                  metrics=['mae', 'mse'])
    return model

# 生成训练,测试数据
def generateData():
    train_dataset = []
    test_dataset = []
    for i in range(0, 5):
        train_dataset.append([i, i + 2])
    for i in range(6, 10):
        test_dataset.append([i, i + 2])
    return np.array(train_dataset, dtype=np.float), np.array(test_dataset,dtype=np.float)

train_dataset, test_dataset = generateData()
# 构建Dataframe格式的dataset
train_dataset = pd.DataFrame(train_dataset)
test_dataset = pd.DataFrame(test_dataset)
# 用第2列(下标为1即y值)的数据作为label
train_labels = train_dataset.pop(1)
test_labels = test_dataset.pop(1)

# 训练1000个epoch
Epochs = 1000

model = buildModel()
# 开始训练
history = model.fit(train_dataset, train_labels, epochs=Epochs, validation_split=0.0, verbose=0)
# 训练结果
hist = pd.DataFrame(history.history)
print(hist)

运行结果如下所示:

     loss  mae  mse
0     0.0  0.0  0.0
1     0.0  0.0  0.0
2     0.0  0.0  0.0
3     0.0  0.0  0.0
4     0.0  0.0  0.0
..    ...  ...  ...
995   0.0  0.0  0.0
996   0.0  0.0  0.0
997   0.0  0.0  0.0
998   0.0  0.0  0.0
999   0.0  0.0  0.0
[1000 rows x 3 columns]

可以看到,由于我们设置了网络的初始参数w=1.0,b=2.0,即网络初始的参数就满足真实的结果y=1.0*x+2.0,因此训练时第一次的误差就是0.0,即可达到最优解,此时可以直接结束训练,但是此处为了继续观察驯良过程并未手动结束。
当我们修改网络的初始参数时,例如我们将相应的代码改为:

  model = tf.keras.Sequential([
        layers.Dense(1, kernel_initializer=tf.keras.initializers.ones(),
                     bias_initializer=tf.keras.initializers.constant([3.0]))
    ])

  使用w=1.0,b=3.0初始网络参数。重新训练后的结果如下:

         loss       mae       mse
0    1.000000  1.000000  1.000000
1    0.981136  0.990513  0.981136
2    0.967663  0.983669  0.967663
3    0.956508  0.977957  0.956508
4    0.946696  0.972899  0.946696
..        ...       ...       ...
995  0.000418  0.016978  0.000418
996  0.000399  0.016265  0.000399
997  0.000381  0.016228  0.000381
998  0.000363  0.015520  0.000363
999  0.000346  0.015484  0.000346

[1000 rows x 3 columns]

在epoch=0时,由于初始参数b=3.0,而真实的的偏移参数b应该为2.0,因此``loss=1.0 mae=1.0 mse=1.0```。经过1000次训练后误差可以减小到0.000346。

三、总结

上面两个实验结果对比可以表明,在使用keras构建神经网络时可以使用参数kernel_initializerbias_initializer初始化网络的w和b参数。手动初始化网络参数对于减小训练次数,提高网络训练精度具有重要意义。

四、参考

[1]. Layer weight initializers
[2]. keras系列(一):参数设置

posted on 2021-07-07 14:20  刘好念  阅读(102)  评论(0)    收藏  举报  来源