tensorflow2 神经网络模型构建4种方法

19 篇文章 2 订阅
9 篇文章 2 订阅

学习目标:

tensorflow2模型构建4种方法,掌握其优缺点。
顺便:compile是TensorFlow2专门用来训练模型的,很方便,避免了写Gradenttape那种形式化结构,直观明了,一定要掌握。


学习内容:

1、 使用现有的预训练模型 2、 Keras Sequential模式建立模型(不推荐) 3、 Functional API 函数api建立模型(最常用,可构造复杂网络) 4、tensorflow构建模型Class

1. 使用现有的预训练模型

使用现有模型有两种
1、 一种是线下训练,然后保存模型,线上加载运行。就是常规的模型部署
2、 使用别人训练好共享出来的模型,加载到自己的业务场景中,适应性调整参数。这个过程美其名曰:迁移学习

线下训练,线上加载运行

示例:我们线下训练一个3层结构的全连接神经网络,用来预测iris花的品种分类,然后保存训练好的模型,格式为h5。然后线上部署时,把模型进行加载。

线下训练
import tensorflow as tf
import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split

data = load_iris()
iris_data = np.float32(data.data)
iris_target = (data.target)
iris_target = np.float32(tf.keras.utils.to_categorical(iris_target,num_classes=3))

x_train,x_test,y_train ,y_test = train_test_split(iris_data,iris_target,test_size=0.2,shuffle=True)
# print(x_train)
# print(y_train)
train_data = tf.data.Dataset.from_tensor_slices((x_train,y_train)).batch(128)
test_data = tf.data.Dataset.from_tensor_slices((x_test,y_test))

input_xs = tf.keras.Input(shape=(4),name='input_xs')
out = tf.keras.layers.Dense(32,activation='relu',name='dense_1')(input_xs)
out = tf.keras.layers.Dense(64,activation='relu',name='dense_2')(out)
logits = tf.keras.layers.Dense(3,activation='softmax',name='logits')(out)
model = tf.keras.Model(inputs=input_xs,outputs = logits)
opt = tf.keras.optimizers.Adam(1e-3)
model.compile(optimizer=opt,loss=tf.keras.losses.categorical_crossentropy,metrics=['accuracy','mse'])
model.fit(train_data,epochs=500)
score = model.evaluate(x=x_test,y=y_test)
print('last score:',score)
model.save('./saver/the_save_models.h5')

然后模型为./saver/the_save_models.h5。因此在线上部署时,我们需要把训练好的模型加载回来。

线上加载

我们把训练好的模型./saver/the_save_models.h5加载回来。

import tensorflow as tf
import numpy as np
from sklearn.datasets import load_iris

data = load_iris()
iris_data = np.float32(data.data)
iris_target = (data.target)
iris_target = np.float32(tf.keras.utils.to_categorical(iris_target))
new_model = tf.keras.models.load_model('./saver/the_save_models.h5')
new_prediction = new_model(iris_data)

print(tf.argmax(new_prediction,axis=-1))

迁移学习

keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',
                                input_tensor=None, input_shape=None,
                                pooling=None,
                                classes=1000)

案例1:猫狗分类
或者:

model = tf.keras.applications.MobileNetV2(weights=None, classes=5)

2.Keras Sequential模式建立模型(不推荐,灵活性太差)

在这里插入图片描述
可以看到这里并没有输入x,没法对中间计算到的变量,做一些个性化的操作。不灵活。

3.Functional API 函数api建立模型(最常用,可构建复杂网络)

复杂情况包括:

  • 多输入模型–多个特征拼接
  • 多输出模型–多个预测结果
  • 具有共享层的模型(同一层被调用多次)–电信的比如残差网络
  • 具有非序列数据流的模型(例如,剩余连接)

这种方式就是各个层都是一个函数,有明确的输入和输出,可以对输入和输出进行个性化的操作后,送入下一层,也可以复用。
通过函数的叠加就可以实现,一般使用这种方法,将模型封装成一个模型函数。
下面示例一个多个输入(两组特征值)多个输出(两组预测结果)的例子。

import tensorflow as tf
import numpy as np
from sklearn.datasets import load_iris
data = load_iris()

iris_data = np.float32(data.data)
iris_data_1 = []
iris_data_2 = []

for iris in iris_data:
    iris_data_1.append(iris[:2])
    iris_data_2.append(iris[2:])
iris_label = np.float32(data.target)
iris_target = np.float32(tf.keras.utils.to_categorical(data.target,num_classes=3))
train_data = tf.data.Dataset.from_tensor_slices(((iris_data_1,iris_data_2),(iris_target,iris_label))).batch(128)
input_xs_1 = tf.keras.Input(shape=(2),name='input_xs_1')
input_xs_2 = tf.keras.Input(shape=(2),name='input_xs_2')
input_xs = tf.concat([input_xs_1,input_xs_2],axis=-1)
out = tf.keras.layers.Dense(32,activation='relu',name = 'dense_1')(input_xs)
out = tf.keras.layers.Dense(64,activation='relu',name='dense_2')(out)
logits = tf.keras.layers.Dense(3,activation='softmax',name='prediction')(out)  # out from prediction 1
label= tf.keras.layers.Dense(1,name='label')(out) # out from prediction 2
model = tf.keras.Model(inputs = [input_xs_1,input_xs_2],outputs = [logits,label])
opt = tf.keras.optimizers.Adam(learning_rate=1e-3)
def my_MSE(y_ture,y_pred):
    my_loss = tf.reduce_mean(tf.square(y_ture-y_pred))
    return my_loss
model.compile(optimizer=opt,loss={'prediction':tf.keras.losses.categorical_crossentropy,'label':my_MSE},loss_weights={'prediction':0.1,'label':0.5},metrics=['accuracy','mse'])
model.fit(x=train_data,epochs=500)
score = model.evaluate(train_data)
print('last score is :',score)

4.tf构建模型Class

也就是自定义层级结构,最灵活,当然灵活的代价是增加了代码量,根据实际情况而定。如果Functional能满足要求,不必非要自己构建class。
自定义层级的class,需要继承父类Layers,TensorFlow2 自定义的层级需要实现3个函数init、buil、call。

  • init --初始化所有参数,根须需要设定层中的参数,比如输出的维度,卷积核数目和大小。
  • buil(只有实现了此方法,才能用compile,否则,需要手写Gradentape的繁琐结构),对所有的可变参数进行定义
  • call–模型的计算,全部放这里。
    在书《TensorFlow 2.0 深度学习从零开始学》第98页写到。

这里明确一下,自定义层,class的初始化参数,是给到init中,后面的input,形状是给到input_shape,张量是给到input_tensor。
比如Mylayer(32)(x),其中,32赋值给init函数的变量,而x.shape赋值给input_shape,而x赋值给了input_tensor。

例子:以下代码自定义了一个卷积(conv)层预测MNIST手写集。代码稍微有点复杂。需要耐心

import numpy as np
import tensorflow as tf
mnist = tf.keras.datasets.mnist
(x_train,y_train),(x_test,y_test) = mnist.load_data()
x_train,x_test = x_train/255.0,x_test/255.0
x_train = tf.expand_dims(x_train,-1)
y_train = np.float32(tf.keras.utils.to_categorical(y_train,num_classes=10))
x_test = tf.expand_dims(x_test,-1)
y_test = np.float32(tf.keras.utils.to_categorical(y_test,num_classes=10))
batch_size = 512
train_dataset = tf.data.Dataset.from_tensor_slices((x_train,y_train)).batch(batch_size).shuffle(batch_size*10)
test_dataset = tf.data.Dataset.from_tensor_slices((x_test,y_test)).batch(batch_size).shuffle(batch_size*10)

#自定义层
class MyLayer(tf.keras.layers.Layer):
    def __init__(self,kernel_size,filter):
        self.filter = filter
        self.kernel_size = kernel_size
        super(MyLayer,self).__init__()
    def build(self,input_shape):
        self.weight = tf.Variable(tf.random.normal([self.kernel_size,self.kernel_size,input_shape[-1],self.filter]))
        self.bias = tf.Variable(tf.random.normal([self.filter]))
        super(MyLayer,self).build(input_shape)   # Be sure to call this somewhere !
    def call(self,input_tensor):
        conv = tf.nn.conv2d(input_tensor,self.weight,strides=[1,2,2,1],padding='SAME')
        conv = tf.nn.bias_add(conv,self.bias)
        out = tf.nn.relu(conv) + conv   # 此处为残差神经网络的构造
        return out
input_xs = tf.keras.Input(shape=[28,28,1])
conv = tf.keras.layers.Conv2D(32,3,padding="SAME",activation='relu')(input_xs)
# 使用自定义层
conv = MyLayer(32,3)(conv)
conv = tf.keras.layers.BatchNormalization()(conv)
conv = tf.keras.layers.Conv2D(64,3,padding="SAME",activation='relu')(conv)
conv = tf.keras.layers.MaxPooling2D(strides=[2,2])(conv)
conv = tf.keras.layers.Dropout(0.2)(conv)
conv = tf.keras.layers.Conv2D(128,3,padding='SAME',activation='relu')(conv)
flat = tf.keras.layers.Flatten()(conv)
dense = tf.keras.layers.Dense(512,activation='relu')(flat)
logits = tf.keras.layers.Dense(10,activation='softmax')(dense)
model = tf.keras.Model(inputs = input_xs,outputs = logits)
print(model.summary())
model.compile(optimizer=tf.keras.optimizers.Adam(1e-3),loss=tf.keras.losses.categorical_crossentropy,metrics=['accuracy','mse'])
model.fit(train_dataset,epochs=10)
score = model.evaluate(test_dataset)
print('score is :',score)
model.save('./saver/mymodel.h5')

运行结果:

在这里插入图片描述

总结:

重点掌握:

  • 1.使用Functional的方式定义模型
  • 2.使用compile的方式定义模型的优化更新
  • 3
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值