【初级】keras机器学习基础知识|总结

学习记录

基于Tensorflow的教程


电影评论文本分类

tf.keras.layers.Embedding

1 embedding的input_dim和output_dim、input_length参数
参数讲解
Emdedding方法的参数解释:

  1. batch_size不需要多说,所有设计它的计算都从“加速模型参数更新”的角度思考。

  2. input_dim:它的值代表一个界限,一个输入矩阵[batch_size, input_length]中的值不能超越的界限。也就是说该输入矩阵中的数字都是处于(0, input_dim)之间的。另外,其在自然语言建模中时常代表vocabulary size。

  3. output_dim:该参数的理解要从Embedding方法的作用角度理解:Turns positive integers (indexes) into dense vectors of fixed size——将正整数转换为固定size大小的稠密向量,其中,该固定size即是output_dim的值;稠密向量的概念是相对于one-hot编码的非1即0的稀疏向量形式,稠密向量中各个位置的值是可训练的参数。因此说,output_dim是Embedding价值的关键。

  4. input_length:视情况,本人未深究。
    在这里插入图片描述
    Embdding方法于自然语言模型中的现实意义

  5. inputs层只需要一个一维的数组即可,其维度大小代表input_length,即每段评论希望用多少维度的向量来表示,其中input_length即是该向量的维度,同时它也可称为每段平均的特征数目即num_Features = num_words。

  6. Vocab_size 即 input_dim 表示语料库中单词的总数,**输入向量(batch_size,input_length)的一个整数,在经过Embdding处理成为一个output_dim维的Embdding vector向量过程中,限定该Embdding vector中新元素的取值范围处于(0,input_dim)input_dim

GlobalAveragePooling1D方法的解释

  1. 简单地说,将一个一维向量中的元素做了平均处理得到一个标量。见下图:
input_shape = (2, 3, 4)
x = tf.random.normal(input_shape)
y = tf.keras.layers.GlobalAveragePooling1D()(x)
print(x)
print(y)
print(y.shape)
##########
tf.Tensor(
[[[ 0.4384202  -0.3591519   1.5297682  -0.16539608]
  [ 1.5761777   0.52934337  1.2045766   0.365361  ]
  [ 0.8673663  -1.8493764   0.9721958   0.21659349]]

 [[-0.22293754 -0.3404366   0.5198015   0.78210837]
  [ 0.508692    1.7574197   1.1817068  -0.16306582]
  [-1.5862045  -1.8136072  -0.7985062  -1.397476  ]]], shape=(2, 3, 4), dtype=float32)
  
tf.Tensor(
[[ 0.96065474 -0.5597283   1.2355136   0.1388528 ]
 [-0.43348336 -0.13220803  0.30100068 -0.25947782]], shape=(2, 4), dtype=float32)
 
(2, 4)

在这里插入图片描述

使用 Keras 和 Tensorflow Hub 对电影评论进行

① 记录设备运行的包版本与TF执行模型与设备

print("Version: ", tf.__version__)
print("Eager mode: ", tf.executing_eagerly())
print("Hub version: ", hub.__version__)
print("GPU is", "available" if tf.config.experimental.list_physical_devices("GPU") else "NOT AVAILABLE")
###===========####
Version:  2.3.0
Eager mode:  True
Hub version:  0.9.0
GPU is available

② IMDB 数据集的数据分析

  1. 通过load函数将数据集分成训练集、验证集、测试集三种。note: 每个样本是一个字符串包含一句话
train_data, validation_data, test_data = tfds.load(
    name="imdb_reviews", 
    split=('train[:60%]', 'train[60%:]', 'test'),
    as_supervised=True)
train_examples_batch
train_labels_batch
##===============
<tf.Tensor: shape=(10,), dtype=string, numpy=
array([b"This was an absolutely terrible movie. Don't be lured in by Christopher Walken",
       b'I have been known to fall asleep during films, but this is usually due',
       b'Mann photographs the Alberta Rocky Mountains in a superb fashion, and',
       b'This is the kind of film for a snowy Sunday afternoon when the rest of',
       b'As others have mentioned, all the women that go nude in this film are',
       b"This is a film which should be seen by anybody interested in, ",
       b'Okay, you have:<br /><br />Penelope Keith as Miss Herringbone-Tweed ',
       b'The film is based on a genuine 1950s novel.<br /><br />Journalist ',
       b'I really love the sexy action and sci-fi films of the sixties ',
       b'Sure, this one isn\'t really a blockbuster, nor '],
      dtype=object)>

<tf.Tensor: shape=(10,), dtype=int64, numpy=array([0, 0, 0, 1, 1, 1, 0, 0, 0, 0])>
  1. 使用迁移学习进行字符串的分割,最终将一个句子构造成“嵌入向量”.
    一个shape的转换过程大致为:
    —> a string
    —> 非固定单词个数的单词向量[num_words_nofixed, ]
    —> 通过padding转化为固定单词个数的单词向量[num_words, ])
    —> 嵌入向量转换(num_words, embedding_dimension)(同EmbddingAPI中的output_dim),本例子中为20。
    迁移学习代码如下:
    Note: 经过迁移学习后,shape变为(num_words, embedding_dimension)
embedding = "https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1 "
hub_layer = hub.KerasLayer(embedding, input_shape=[], 
                           dtype=tf.string, trainable=True)
hub_layer(train_examples_batch[:3])
#####=============################## 
<tf.Tensor: shape=(3, 20), dtype=float32, numpy=
array([[ 1.765786  , -3.882232  ,  3.9134233 , -1.5557289 , -3.3362343 ,
        -1.7357955 , -1.9954445 ,  1.2989551 ,  5.081598  , -1.1041286 ,
        -2.0503852 , -0.72675157, -0.65675956,  0.24436149, -3.7208383 ,
         2.0954835 ,  2.2969332 , -2.0689783 , -2.9489717 , -1.1315987 ],
       [ 1.8804485 , -2.5852382 ,  3.4066997 ,  1.0982676 , -4.056685  ,
        -4.891284  , -2.785554  ,  1.3874227 ,  3.8476458 , -0.9256538 ,
        -1.896706  ,  1.2113281 ,  0.11474707,  0.76209456, -4.8791065 ,
         2.906149  ,  4.7087674 , -2.3652055 , -3.5015898 , -1.6390051 ],
       [ 0.71152234, -0.6353217 ,  1.7385626 , -1.1168286 , -0.5451594 ,
        -1.1808156 ,  0.09504455,  1.4653089 ,  0.66059524,  0.79308075,
        -2.2268345 ,  0.07446612, -1.4075904 , -0.70645386, -1.907037  ,
         1.4419787 ,  1.9551861 , -0.42660055, -2.8022065 ,  0.43727064]],
      dtype=float32)>

③ 完整模型与损失函数、优化器选择

embedding = "https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1 "
hub_layer = hub.KerasLayer(embedding, input_shape=[], 
                           dtype=tf.string, trainable=True)
                        
model = tf.keras.Sequential()
model.add(hub_layer)
model.add(tf.keras.layers.Dense(16, activation='relu'))
model.add(tf.keras.layers.Dense(1))
model.summary()
  1. 二分类问题且模型的输出为概率值(经过sigmoid的单一单元层),所以使用binary_crossentropy 损失函数。
  2. model.fit函数中的metrics**是在每次epoch后进行计算并记录的,训练集与测试集都是如此。**而model.evaluatemetrics则是仅计算一次的。原因就在于epoch的次数是否仅为1.

预测燃油效率

① 数据预处理

  1. 特征如果代表的是类别,应该将其转换为哑编码形式。
origin = dataset.pop('Origin')
dataset['USA'] = (origin == 1)*1.0
dataset['Europe'] = (origin == 2)*1.0
dataset['Japan'] = (origin == 3)*1.0
dataset.tail()

在这里插入图片描述在这里插入图片描述
2. 观察seaborn下的特征间相关性图PairGrid
对角线以外的图像表示不同特征之间的相关性分布散点图;对角线中的图像则显示单特征的“变量分布”
在这里插入图片描述

  1. Pandas数据集分离出“标签”的方式
train_labels = train_dataset.pop('MPG')
test_labels = test_dataset.pop('MPG')
  1. 数据规范化的逻辑观点
    使用不同的尺度和范围对特征归一化是好的实践。尽管模型可能 在没有特征归一化的情况下收敛,但它会使得模型训练更加复杂,并会造成生成的模型依赖输入所使用的单位选择。

由数据规范化引出的“数据预处理”的顶级处理原则:训练集、验证集、测试集三者的预处理必须一致,从根本上说是使得三者的统计分布一致。比如哑编码处理时,应该是集合在一起进行哑编码处理!

② 模型的构建过程

  1. 构建模型时,将模型整合到一个函数中。
    为了与inputs的数据在shapa方面的衔接,一般会在第一层中点明input_shape。
def build_model():
  model = keras.Sequential([
    layers.Dense(64, activation='relu', input_shape=[len(train_dataset.keys())]),
    layers.Dense(64, activation='relu'),
    layers.Dense(1)
  ])

  optimizer = tf.keras.optimizers.RMSprop(0.001)

  model.compile(loss='mse',
                optimizer=optimizer,
                metrics=['mae', 'mse'])
  return model
  1. 自定义callback函数的例子配合早停法
# 通过为每个完成的时期打印一个点来显示训练进度
class PrintDot(keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs):
    if epoch % 100 == 0: print('')
    print('.', end='')

EPOCHS = 1000

history = model.fit(
  normed_train_data, train_labels,
  epochs=EPOCHS, validation_split = 0.2, verbose=0,
  callbacks=[PrintDot()])

###############################
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................
....................................................................................................

配合早停法后

model = build_model()

# patience 值用来检查改进 epochs 的数量
early_stop = keras.callbacks.EarlyStopping(monitor='val_loss', patience=10)

history = model.fit(normed_train_data, train_labels, epochs=EPOCHS,
                    validation_split = 0.2, verbose=0, callbacks=[early_stop, PrintDot()])

plot_history(history) # 在本文的下一节有具体代码
################################
....................................................................................................
...........................

在这里插入图片描述

  1. history我们都知道是model.fit的返回结果。一般是直接将history.history的结果扔给plt进行展示,但是如果用pandas进行数据的结构化展示,从可视化的角度来看,不乏便利性质。
hist = pd.DataFrame(history.history)
hist['epoch'] = history.epoch
hist.tail()

在这里插入图片描述

  1. Pandas处理后的history.history能用于Tensorboard以外的Plot图像绘制,这样便于论文写作。
def plot_history(history):
  hist = pd.DataFrame(history.history)
  hist['epoch'] = history.epoch

  plt.figure()
  plt.xlabel('Epoch')
  plt.ylabel('Mean Abs Error [MPG]')
  plt.plot(hist['epoch'], hist['mae'],
           label='Train Error')
  plt.plot(hist['epoch'], hist['val_mae'],
           label = 'Val Error')
  plt.ylim([0,5])
  plt.legend()

  plt.figure()
  plt.xlabel('Epoch')
  plt.ylabel('Mean Square Error [$MPG^2$]')
  plt.plot(hist['epoch'], hist['mse'],
           label='Train Error')
  plt.plot(hist['epoch'], hist['val_mse'],
           label = 'Val Error')
  plt.ylim([0,20])
  plt.legend()
  plt.show()


plot_history(history)

在这里插入图片描述

  1. 测试集的metrics的价值分析。
    除了直白的告诉你,loss,mae, mse的值。
loss, mae, mse = model.evaluate(normed_test_data, test_labels, verbose=2)

print("Testing set Mean Abs Error: {:5.2f} MPG".format(mae))

还可以做真实值与预测值的相关性分析,以直观观察模型在测试集中的拟合效果。

test_predictions = model.predict(normed_test_data).flatten()

plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values [MPG]')
plt.ylabel('Predictions [MPG]')
plt.axis('equal')
plt.axis('square')
plt.xlim([0,plt.xlim()[1]])
plt.ylim([0,plt.ylim()[1]])
_ = plt.plot([-100, 100], [-100, 100])

在这里插入图片描述
然而,最为人称绝的是:绘制误差的直方图分布以辨识误差的产生是否是因为样本数量很小而导致的。

error = test_predictions - test_labels
plt.hist(error, bins = 25)
plt.xlabel("Prediction Error [MPG]")
_ = plt.ylabel("Count")

在这里插入图片描述
它不是完全的高斯分布,但我们可以推断出,这是因为样本的数量很小所导致的。(官网上的推断!让人叫绝)

保存和恢复模型

保存的好处在于:

  1. 模型可以从任意中断中恢复,并避免耗费比较长的时间在训练上;
  2. 可以共享您的模型,而其他人可以通过您的模型来重新创建工作;
  3. 共享数据有助于其他人了解模型的工作原理,并使用新数据自行尝试

① checkpoints的形式

  1. tf.keras.callbacks.ModelCheckpoint允许在训练的过程中和结束时回调保存的模型参数,而不含网络结构
# 1 model定义
def create_model():
	model = tf.keras.models.Sequential
	model.compile
	return model

# 2 创建一个基本的模型实例
model = create_model()

# 3 CheckPoints的回调用法
# 3.1 基本配置
checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
# 3.2 创建一个保存模型权重的回调方法
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
                                                 save_weights_only=True,
                                                 verbose=1)
# 3.3 使用新的回调训练模型
model.fit(train_images, 
          train_labels,  
          epochs=10,
          validation_data=(test_images,test_labels),
          callbacks=[cp_callback])  # 通过回调训练

#######################  训练完成后  ###########################
# 1 创建一个模型结构(以调用checkpoint中的参数)
model = create_model()
# 2 从checkpoint中加载模型权重参数(且是最新的)
latest = tf.train.latest_checkpoint(checkpoint_dir)
model.load_weights(latest)
# 3 基于checkpoint中的权重参数 进行评估模型
loss,acc = model.evaluate(test_images,  test_labels, verbose=2)
# 4 基于checkpoint 中的权重参数 重新开始训练
model.fit(train_images, 
          train_labels,  
          epochs=10,
          validation_data=(test_images,test_labels),
          callbacks=[cp_callback])  # 通过回调训练

② checkpoint回调选项和checkpoint文件介绍

  1. ModelCheckpoint的几个选项的说明.
# 1 为checkpoint提供唯一名称: 在文件名中包含 epoch (使用 `str.format`)
checkpoint_path = "training_2/cp-{epoch:04d}.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)

# 2 调整checkpoint的频率 :创建一个回调,每 5 个 epochs 保存模型的权重
cp_callback = tf.keras.callbacks.ModelCheckpoint(
    filepath=checkpoint_path, 
    verbose=1, 
    save_weights_only=True,
    period=5)
  1. checkpoint的几个默认行为:
# 1 checkpoint文件下 的 1+ 5*2 个文件。
# 其中 1 表示checkpoint基本信息文件;2 表示cp-0000.ckpt.data-00000-of-00001和cp-0000.ckpt.index两个文件; 5表示,默认的 tensorflow 格式仅保存最近的5个 checkpoint。

ModelCheckpoint训练中自动保存与Model.save_weights的手动保存

# 1 Model.save_weights 手动保存:具体的应用时候不太清楚,可能需要在更加灵活的场景中使用吧。
# save_weights 的 链接:https://tensorflow.google.cn/api_docs/python/tf/keras/Sequential?hl=en#save_weights

model.save_weights('./checkpoints/my_checkpoint')
model = create_model()
model.load_weights('./checkpoints/my_checkpoint')
# 2 --- ModelCheckpoint 于训练中自动保存。
# 1 model定义
def create_model():
	model = tf.keras.models.Sequential
	model.compile
	return model

# 2 创建一个基本的模型实例
model = create_model()

# 3 CheckPoints的回调用法
# 3.1 基本配置
checkpoint_path = "training_1/cp.ckpt"
checkpoint_dir = os.path.dirname(checkpoint_path)
# 3.2 创建一个保存模型权重的回调方法
cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_path,
                                                 save_weights_only=True,
                                                 verbose=1)
# 3.3 使用新的回调训练模型
model.fit(train_images, 
          train_labels,  
          epochs=10,
          validation_data=(test_images,test_labels),
          callbacks=[cp_callback])  # 通过回调训练

#######################  训练完成后  ###########################
# 1 创建一个模型结构(以调用checkpoint中的参数)
model = create_model()
# 2 从checkpoint中加载模型权重参数(且是最新的)
latest = tf.train.latest_checkpoint(checkpoint_dir)
model.load_weights(latest)
# 3 基于checkpoint中的权重参数 进行评估模型
loss,acc = model.evaluate(test_images,  test_labels, verbose=2)
# 4 基于checkpoint 中的权重参数 重新开始训练
model.fit(train_images, 
          train_labels,  
          epochs=10,
          validation_data=(test_images,test_labels),
          callbacks=[cp_callback])  # 通过回调训练

SavedModel格式–保存模型的参数与网络结构

Note:TensorFlow 的 SavedModel 格式是 TF2.x. 中的默认文件格式。
保存整个模型的好处:可以在 TensorFlow.js中SavedModel或者HDF5借助加载它们,以在 web 浏览器中训练和运行它们;又或者使用 TensorFlow Lite 将它们转换为在移动设备上运行。

  1. 保存命令与加载命令:model.save('saved_model/my_model')tf.keras.models.load_model('saved_model/my_model')实现。
model = create_model()
model.fit(train_images, train_labels, epochs=5)
# 1 模型的保存
model.save('saved_model/my_model') 
# 2 模型(网络与参数)的加载
new_model = tf.keras.models.load_model('saved_model/my_model')
# 3 模型的使用
loss, acc = new_model.evaluate(test_images,  test_labels, verbose=2)

HDF5格式–保存模型的参数与网络结构

Keras使用 HDF5 标准提供了一种基本的保存格式

  1. 保存和加载命令:model.save('my_model.h5')tf.keras.models.load_model('my_model.h5'),也就是说与SavedModel格式的方法一致。

⑥ 模型的保存和加载的总结

Keras 通过检查网络结构来保存模型。这项技术可以保存一切:

  • 权重值
  • 模型的架构
  • 模型的训练配置(您传递给编译的内容)
  • 优化器及其状态(如果有的话)(这使您可以在中断的地方重新开始训练

Keras 无法保存 v1.x 优化器(来自 tf.compat.v1.train),因为它们与检查点不兼容。对于 v1.x 优化器,您需要在加载-失去优化器的状态后,重新编译模型。

HDF5 和 SavedModel 之间的主要区别在于,HDF5 使用对象配置保存模型结构,而 SavedModel 保存执行图。

五 使用Keras Tuner 调整超参数

相关链接:

  1. 关于Hyperband调参算法的介绍
  2. keras_tuner库的总结【源自官网Examples】
# 这部分代码学习第二个链接与第一个链接,就可以非常好的搞明白。前提是学完那两个文章。
tuner = kt.Hyperband(model_builder,
                     objective = 'val_accuracy', 
                     max_epochs = 10,
                     factor = 3,
                     directory = 'my_dir',
                     project_name = 'intro_to_kt')                       

官网称下面代码的功能是:在运行超参数搜索之前,定义回调以清除每个训练步骤结束时的训练输出。但是这种考虑是面向Notebook的。在pycharm没什么呈现。

class ClearTrainingOutput(tf.keras.callbacks.Callback):
  def on_train_end(*args, **kwargs):
    IPython.display.clear_output(wait = True)

tuner.search(img_train, label_train, epochs = 10, validation_data = (img_test, label_test), callbacks = [ClearTrainingOutput()])

# Get the optimal hyperparameters
best_hps = tuner.get_best_hyperparameters(num_trials = 1)[0]

print(f"""
The hyperparameter search is complete. The optimal number of units in the first densely-connected
layer is {best_hps.get('units')} and the optimal learning rate for the optimizer
is {best_hps.get('learning_rate')}.
""")

重点在于best_hps = tuner.get_best_hyperparameters(num_trials = 1)[0]

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值