Custom layers

Custom layers

自定义成层只需要 继承tf.keras.layers.Layer 类即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class MyDense(tf.keras.layers.Layer):
# init 可以进行所有与输入无关的初始化
def __init__(self,units =32):
super(MyDense, self).__init__()
self.units = units
# build 可以知道输入张量的形状,并可以进行其余的初始化
def build(self, input_shape):
self.w1 = self.add_weight(shape=(input_shape[-1], self.units),
initializer=tf.keras.initializers.he_normal(),
trainable=True)
self.b1 = self.add_weight(shape=(self.units),
initializer=tf.keras.initializers.zeros(),
trainable=True)
# 在这里进行正向计算
def call(self, inputs):
return inputs@self.w1+self.b1

Models: composing layers组合层

组合层 更容易定义自己的层块

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
32
33
34
35
36
37
38
39
40
41
42
43
44
class MLPBlock(tf.keras.layers.Layer):

def __init__(self):
super(MLPBlock, self).__init__()
self.Dense1 = MyDense(256)
self.Dense2 = MyDense(128)
self.Dense3 = MyDense(10)

def call(self, inputs):
x = self.Dense1(inputs)
x = tf.nn.relu(x)
x = self.Dense2(x)
x = tf.nn.relu(x)
x = self.Dense3(x)
x = tf.nn.softmax(x)
return x


# 注意model训练数据 不能 numpy 与 tensor 混用。
#在Tensorflow中有两种方法one-hot,看下面部分
test1 = np.random.randn(50, 64 * 64)
test1_y = np.random.randint(0, 10, size=(50,))
# 将标签one-hot化
test1_y = tf.keras.utils.to_categorical(test1_y, num_classes=10)



# 函数式
inputs = tf.keras.Input(shape=(64 * 64,))
X = MLPBlock()(inputs)
model = tf.keras.models.Model(inputs= inputs, outputs = X)

# 序列式
# model = tf.keras.models.Sequential([
# MLPBlock()
# ])
model.build(input_shape=(None,64*64))

model.compile(optimizer=tf.keras.optimizers.SGD(),
loss=tf.keras.losses.mean_squared_error,
metrics=['acc']
)

model.fit(test1, test1_y, epochs=10)

one-hot

在tensorflow中有 两种 将标签one-hot化的方法。

  • tf.one-hot()

  • tf.keras.utils.to_categorical()

tf.one-hot()

tf.one_hot() 是将numpy数组转换为了tensor张量,在用此方法输入数据时 要求输入的x, y 均为tensor, 因此输入data 需要通过tf.constant() 来进行转换。, 同理 利用tf.keras.utils.to_categorical() 时需要x, y 均为numpy

1
2
3
label = np.array([1,2,3,4,8])
print(tf.one_hot(label, depth=10))

1
2
3
4
5
6
tf.Tensor(
[[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]], shape=(5, 10), dtype=float32)

tf.keras.utils.to_categorical()

tf.keras.utils.to_categorical()是直接转换为numpy数组, 相比tf.one-hot() 要对x进行tensor转换要方便许多。

其中在为指定num_classes时,默认输入数据的最大类别来进行处理。

1
print(tf.keras.utils.to_categorical(label, num_classes=10))
1
2
3
4
5
[[0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]]