首先建立一个简单神经网络:

1
2
3
4
5
6
7
8
9
10
import tensorflow as tf

net = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(4, activation=tf.nn.relu),
tf.keras.layers.Dense(1),
])

X = tf.random.uniform((2, 4))
net(X)

访问目标参数

该网络有一个输入层,一个隐藏层,一个输出层,也即两个全连接层。三个层可以用下标0,1,2来进行访问,每个层有权重和偏置两组参数,分别用下标0,1访问,具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 参数w格式满足y=xw+b
# 访问输出层的权重和偏置
print(net.layers[2].weights)

# 访问输出层的偏置
print(net.layers[2].weights[1])

# 访问所有参数
print(net.get_weights())

# 另一种方式用下标0,1,2,3表示隐藏层权重、偏置、输出层权重、输出层偏置。
# 以下输出隐藏层偏置
net.get_weights()[1]

若对于嵌套神经网络访问参数的方式相同。

首先建立嵌套神经网络。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def block1(name):
return tf.keras.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(4, activation=tf.nn.relu)],
name=name)

def block2():
net = tf.keras.Sequential()
for i in range(4):
# 在这里嵌套
net.add(block1(name=f'block-{i}'))
return net

rgnet = tf.keras.Sequential()
rgnet.add(block2())
rgnet.add(tf.keras.layers.Dense(1))
rgnet(X)

这个网络的结构如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Input
|
|--> block2
| |
| |--> block1 (block-0)
| | |
| | |--> Flatten
| | |
| | |--> Dense(4) - ReLU
| |
| |--> block1 (block-1)
| | |
| | |--> Flatten
| | |
| | |--> Dense(4) - ReLU
| |
| |--> block1 (block-2)
| | |
| | |--> Flatten
| | |
| | |--> Dense(4) - ReLU
| |
| |--> block1 (block-3)
| |
| |--> Flatten
| |
| |--> Dense(4) - ReLU
|
|
|--> Dense(1)

若想访问第一个主要的块中、第二个子块的输出层的偏置项,那么可以用以下语句来询问。

1
rgnet.layers[0].layers[1].layers[1].weights[1]

参数初始化

可以使用内置初始化,也可以自定义,可以对偏置和权重分别初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 将权重初始化为正态分布,将偏置初始化为0
net = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(
4, activation=tf.nn.relu,
kernel_initializer=tf.random_normal_initializer(mean=0, stddev=0.01),
bias_initializer=tf.zeros_initializer()),
tf.keras.layers.Dense(1)])

# 第一个全连接层权重用Xavier初始化,第二个全连接层权重初始化为常数1
net = tf.keras.models.Sequential([
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(
4,
activation=tf.nn.relu,
kernel_initializer=tf.keras.initializers.GlorotUniform()),
tf.keras.layers.Dense(
1, kernel_initializer=tf.keras.initializers.Constant(1)),
])

保存参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class MLP(tf.keras.Model):
def __init__(self):
super().__init__()
self.flatten = tf.keras.layers.Flatten()
self.hidden = tf.keras.layers.Dense(units=256, activation=tf.nn.relu)
self.out = tf.keras.layers.Dense(units=10)

def call(self, inputs):
x = self.flatten(inputs)
x = self.hidden(x)
return self.out(x)

net = MLP()
X = tf.random.uniform((2, 20))
Y = net(X)

# 保存参数
net.save_weights('mlp.params')

# 调用参数
clone = MLP()
clone.load_weights('mlp.params')