Skip to content

Commit 1134e90

Browse files
committed
第7章代码及详解
1 parent 4502217 commit 1134e90

33 files changed

+360
-0
lines changed

chapter7/custom-callback.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import keras
2+
import numpy as np
3+
4+
5+
class ActivationLogger(keras.callbacks.Callback):
6+
7+
def set_model(self, model):
8+
# 这个方法会在父模型训练前被调用
9+
self.model = model
10+
layer_outputs = [layer.output for layer in model.layers]
11+
# 这是一个model实例,返回每层的激活值
12+
self.activations_model = keras.models.Model(model.input, layer_outputs)
13+
14+
def on_epoch_end(self, epoch, logs=None):
15+
if self.validation_data is None:
16+
raise RuntimeError('Requires validation_data.')
17+
18+
# 获得验证集的第一个输入样本
19+
validation_sample = self.validation_data[0][0:1]
20+
activations = self.activations_model.predict(validation_sample)
21+
# 保存数组到硬盘
22+
f = open('activations_at_epoch_' + str(epoch) + '.npz', 'w')
23+
np.savez(f, activations)
24+
f.close()

chapter7/functional_api.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from keras import Input, layers
2+
from keras.models import Sequential, Model
3+
import numpy as np
4+
5+
# 把层看作一个函数
6+
# 这是一个张量
7+
input_tensor = Input(shape=(32,))
8+
9+
# 一层是一个函数
10+
dense = layers.Dense(32, activation='relu')
11+
12+
# 一层调用一个张量,然后返回一个张量
13+
output_tensor = dense(input_tensor)
14+
15+
# 与序列模型等价的functional API
16+
# 序列模型
17+
seq_model = Sequential()
18+
seq_model.add(layers.Dense(32, activation='relu', input_shape=(64,)))
19+
seq_model.add(layers.Dense(32, activation='relu'))
20+
seq_model.add(layers.Dense(10, activation='softmax'))
21+
22+
# functional API
23+
input_tensor = Input(shape=(64,))
24+
x = layers.Dense(32, activation='relu')(input_tensor)
25+
x = layers.Dense(32, activation='relu')(x)
26+
output_tensor = layers.Dense(10, activation='softmax')(x)
27+
28+
# 把一个输入张量和一个输出张量变成一个模型
29+
model = Model(input_tensor, output_tensor)
30+
31+
model.summary()
32+
33+
# 如果输入张量和输出张量没有关联,将会报错
34+
# unrelated_input = Input(shape=(32,))
35+
# bad_model = Model(unrelated_input, output_tensor)
36+
37+
# 编译、训练和评估是一样的
38+
# 编译模型
39+
model.compile(optimizer='rmsprop',
40+
loss='categorical_crossentropy')
41+
42+
# 生成Numpy的数据去训练
43+
x_train = np.random.random((1000, 64))
44+
y_train = np.random.random((1000, 10))
45+
46+
# 训练模型
47+
model.fit(x_train, y_train, epochs=10, batch_size=128)
48+
49+
# 评估模型
50+
score = model.evaluate(x_train, y_train)

chapter7/inception-module.py

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from keras import layers
2+
from keras import Input
3+
4+
# 假定x是一个四维张量
5+
x = Input(shape=(None,), dtype='int32')
6+
7+
# 每个分支的输出必须是同样大小
8+
branch_a = layers.Conv2D(128, 1, activation='relu', strides=2)(x)
9+
10+
branch_b = layers.Conv2D(128, 1, activation='relu')(x)
11+
branch_b = layers.Conv2D(128, 3, activation='relu', strides=2)(branch_b)
12+
13+
branch_c = layers.AveragePooling2D(3, strides=2, activation='relu')(x)
14+
branch_c = layers.Conv2D(128, 3, activation='relu')(branch_c)
15+
16+
branch_d = layers.Conv2D(128, 1, activation='relu')(x)
17+
branch_d = layers.Conv2D(128, 3, activation='relu')(branch_d)
18+
branch_d = layers.Conv2D(128, 3, activation='relu', strides=2)(branch_d)
19+
20+
output = layers.concatenate([branch_a, branch_b, branch_c, branch_d], axis=-1)

chapter7/layer-weight-sharing.py

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from keras import layers
2+
from keras import Input
3+
from keras.models import Model
4+
5+
# 实例化一个LSTM层
6+
lstm = layers.LSTM(32)
7+
8+
left_input = Input(shape=(None, 128))
9+
left_output = lstm(left_input)
10+
11+
# 共用lstm层的权重
12+
right_input = Input(shape=(None, 128))
13+
right_output = lstm(right_input)
14+
15+
# 构建一个分类器
16+
merged = layers.concatenate([left_output, right_output], axis=-1)
17+
predictions = layers.Dense(1, activation='sigmoid')(merged)
18+
19+
# 实例化、训练模型
20+
model = Model([left_input, right_input], predictions)
21+
# model.fit([left_data, right_data], targets)

chapter7/logs/checkpoint

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
model_checkpoint_path: "keras_embedding.ckpt-0"
2+
all_model_checkpoint_paths: "keras_embedding.ckpt-0"
Binary file not shown.
Binary file not shown.
Binary file not shown.
144 Bytes
Binary file not shown.
131 KB
Binary file not shown.
Binary file not shown.
144 Bytes
Binary file not shown.
131 KB
Binary file not shown.
Binary file not shown.
144 Bytes
Binary file not shown.
131 KB
Binary file not shown.
Binary file not shown.
144 Bytes
Binary file not shown.
131 KB
Binary file not shown.
Binary file not shown.
144 Bytes
Binary file not shown.
131 KB
Binary file not shown.
Binary file not shown.
144 Bytes
Binary file not shown.
131 KB
Binary file not shown.

chapter7/logs/projector_config.pbtxt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
embeddings {
2+
tensor_name: "embed/embeddings:0"
3+
}

chapter7/model.png

39.2 KB
Loading

chapter7/question-answer-model.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from keras.models import Model
2+
from keras import layers
3+
from keras import Input
4+
import numpy as np
5+
6+
text_vocabulary_size = 10000
7+
question_vocabulary_size = 10000
8+
answer_vocabulary_size = 500
9+
10+
# 文本输入是变长的序列
11+
text_input = Input(shape=(None,), dtype='int32', name='text')
12+
13+
# 把文本输入变成大小为64的词向量
14+
embedded_text = layers.Embedding(64, text_vocabulary_size)(text_input)
15+
16+
# LSTM
17+
encoded_text = layers.LSTM(32)(embedded_text)
18+
19+
# 对question做相同步骤
20+
question_input = Input(shape=(None,), dtype='int32', name='question')
21+
embedded_question = layers.Embedding(32, question_vocabulary_size)(question_input)
22+
encoded_question = layers.LSTM(16)(embedded_question)
23+
24+
# 连接encoded_text和encoded_question
25+
concatenated = layers.concatenate([encoded_text, encoded_question], axis=-1)
26+
27+
# 添加一个softmax分类器
28+
answer = layers.Dense(answer_vocabulary_size, activation='softmax')(concatenated)
29+
30+
# 指定二个输入和一个输出
31+
model = Model([text_input, question_input], answer)
32+
model.compile(optimizer='rmsprop',
33+
loss='categorical_crossentropy',
34+
metrics=['acc'])
35+
36+
# 训练模型
37+
# 生成一些模拟数据
38+
num_samples = 500
39+
max_length = 500
40+
text = np.random.randint(1, text_vocabulary_size, size=(num_samples, max_length))
41+
question = np.random.randint(1, question_vocabulary_size, size=(num_samples, max_length))
42+
43+
# one-hot编码
44+
answers = np.random.randint(0, 1, size=(num_samples, answer_vocabulary_size))
45+
46+
# 输入list
47+
model.fit([text, question], answers, epochs=10, batch_size=128)
48+
49+
# 字典方式
50+
model.fit({'text': text, 'question': question}, answers, epochs=10, batch_size=128)

chapter7/residual_connection.py

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from keras import layers
2+
from keras import Input
3+
4+
# 假定x是一个四维张量
5+
x = Input(shape=(None,), dtype='int32')
6+
y = layers.Conv2D(128, 3, activation='relu')(x)
7+
y = layers.Conv2D(128, 3, activation='relu')(y)
8+
y = layers.Conv2D(128, 3, activation='relu')(y)
9+
10+
# 把x加到y的输出中
11+
y = layers.add([y, x])
12+
13+
# --------------------------------------------
14+
# 当特征大小不一样时
15+
# 假定x是一个四维张量
16+
x = Input(shape=(None,), dtype='int32')
17+
y = layers.Conv2D(128, 3, activation='relu')(x)
18+
y = layers.Conv2D(128, 3, activation='relu')(y)
19+
y = layers.MaxPooling2D(2, strides=2)(y)
20+
21+
# 使用线性的降低取样
22+
residual = layers.Conv2D(1, strides=2)(x)
23+
24+
y = layers.add([y, residual])

chapter7/siamese-vision-model.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from keras import layers
2+
from keras import applications
3+
from keras import Input
4+
5+
# 共用convolutional base
6+
xception_base = applications.Xception(weights=None, include_top=False)
7+
8+
# 输入为250*250的RGB图像
9+
left_input = Input(shape=(250, 250, 3))
10+
right_input = Input(shape=(250, 250, 3))
11+
12+
# 调用xception_base两次
13+
left_features = xception_base(left_input)
14+
right_features = xception_base(right_input)
15+
16+
merged_features = layers.concatenate([left_features, right_features], axis=-1)
+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import keras
2+
from keras import layers
3+
from keras.datasets import imdb
4+
from keras.preprocessing import sequence
5+
from keras.utils import plot_model
6+
7+
max_features = 2000
8+
max_len = 500
9+
10+
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=max_features)
11+
x_train = sequence.pad_sequences(x_train, maxlen=max_len)
12+
x_test = sequence.pad_sequences(x_test, maxlen=max_len)
13+
14+
model = keras.models.Sequential()
15+
model.add(layers.Embedding(max_features, 128, input_length=max_len, name='embed'))
16+
model.add(layers.Conv1D(32, 7, activation='relu'))
17+
model.add(layers.MaxPooling1D(5))
18+
model.add(layers.Conv1D(32, 7, activation='relu'))
19+
model.add(layers.GlobalMaxPooling1D())
20+
model.add(layers.Dense(1))
21+
model.summary()
22+
model.compile(optimizer='rmsprop',
23+
loss='binary_crossentropy',
24+
metrics=['acc'])
25+
26+
# 画图
27+
plot_model(model, show_shapes=True, to_file='model.png')
28+
29+
callbacks = [
30+
keras.callbacks.TensorBoard(
31+
# 日志目录
32+
log_dir='logs',
33+
# 每个epoch记录一次activation直方图
34+
histogram_freq=1,
35+
# 每个epoch记录一次词向量数据
36+
embeddings_freq=1,
37+
)
38+
]
39+
40+
history = model.fit(x_train, y_train,
41+
epochs=20,
42+
batch_size=128,
43+
validation_split=0.2,
44+
callbacks=callbacks)

chapter7/three-output-model.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from keras import layers
2+
from keras import Input
3+
from keras.models import Model
4+
5+
vocabulary_size = 50000
6+
num_income_groups = 10
7+
8+
posts_input = Input(shape=(None,), dtype='int32', name='posts')
9+
embedded_posts = layers.Embedding(256, vocabulary_size)(posts_input)
10+
x = layers.Conv1D(128, 5, activation='relu')(embedded_posts)
11+
x = layers.MaxPooling1D(5)(x)
12+
x = layers.Conv1D(256, 5, activation='relu')(x)
13+
x = layers.Conv1D(256, 5, activation='relu')(x)
14+
x = layers.MaxPooling1D(5)(x)
15+
x = layers.Conv1D(256, 5, activation='relu')(x)
16+
x = layers.Conv1D(256, 5, activation='relu')(x)
17+
x = layers.GlobalMaxPooling1D()(x)
18+
x = layers.Dense(128, activation='relu')(x)
19+
20+
# 3个输出
21+
age_prediction = layers.Dense(1, name='age')(x)
22+
income_prediction = layers.Dense(num_income_groups, activation='softmax', name='income')(x)
23+
gender_prediction = layers.Dense(1, activation='sigmoid', name='gender')(x)
24+
25+
model = Model(posts_input, [age_prediction, income_prediction, gender_prediction])
26+
27+
# 多个loss
28+
model.compile(optimizer='rmsprop',
29+
loss=['mse', 'categorical_crossentropy', 'binary_crossentropy'])
30+
31+
# 等价编译
32+
model.compile(optimizer='rmsprop',
33+
loss={'age': 'mse',
34+
'income': 'categorical_crossentropy',
35+
'gender': 'binary_crossentropy'})
36+
37+
# loss weighting
38+
model.compile(optimizer='rmsprop',
39+
loss=['mse', 'categorical_crossentropy', 'binary_crossentropy'],
40+
loss_weights=[0.25, 1., 10.])
41+
42+
# 等价编译
43+
model.compile(optimizer='rmsprop',
44+
loss={'age': 'mse',
45+
'income': 'categorical_crossentropy',
46+
'gender': 'binary_crossentropy'},
47+
loss_weights={'age': 0.25,
48+
'income': 1.,
49+
'gender': 10.})
50+
'''
51+
# 训练模型
52+
model.fit(posts_input, [age_targets, income_targets, gender_targets],
53+
epochs=10, batch_size=64)
54+
55+
# 等价训练
56+
model.fit(posts_input, {'age': age_targets,
57+
'income': income_targets,
58+
'gender': gender_targets},
59+
epochs=10, batch_size=64)
60+
'''

chapter7/using-callbacks.py

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import keras
2+
from keras import Model
3+
4+
callbacks_list = [
5+
# 这个callback会在模型停止优化时打断训练
6+
keras.callbacks.EarlyStopping(
7+
# 监测验证集的准确度,这边应该是val_acc???
8+
monitor='acc',
9+
# 当准确率已经停止优化超过1个epochs,也就是2个epochs,训练将会被打断
10+
patience=1,
11+
),
12+
# 这个callback将会在每个epoch后保存当前的权重
13+
keras.callbacks.ModelCheckpoint(
14+
filepath='my_model.h5',
15+
# 下面2个参数意味着除非val_loss有优化,不然model文件不会被重写
16+
monitor='val_loss',
17+
save_best_only=True,
18+
)
19+
]
20+
21+
model = Model()
22+
23+
# 因为我们监测acc指标,acc应该成为一个度量标准
24+
model.compile(optimizer='rmsprop',
25+
loss='binary_crossentropy',
26+
metrics=['acc'])
27+
28+
'''
29+
model.fit(x, y,
30+
epochs=10,
31+
batch_size=32,
32+
callbacks=callbacks_list,
33+
validation_data=(x_val, y_val))
34+
'''
35+
36+
# 使用ReduceLROnPlateau
37+
callbacks_list = [
38+
keras.callbacks.ReduceLROnPlateau(
39+
# 监测验证集的loss
40+
monitor='val_loss',
41+
# 触发时把学习速率除以10
42+
factor=0.1,
43+
# 在验证集loss停止优化10个epochs时触发
44+
patience=10,
45+
)
46+
]

0 commit comments

Comments
 (0)