栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

# keras学习【入门基础】-- 看完就入门

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

# keras学习【入门基础】-- 看完就入门

前驱课程: 《吴恩达深度学习》

听完课才有一些专有名词的概念

首先是导库
import tensorflow as tf
from tensorflow import keras
张量设置和使用 创建恒定张量
x = tf.constant([[1,3], [1, 2]])
# 可使用.numpy() 改变type
x.numpy()
矩阵创建
# 1/0矩阵
tf.ones(shape=(,))
tf.zeros(shape=(,))
# 正态分布
tf.random.normal(shape=(,), mean=, stddev=)
# 均匀分布
tf.random.uniform(shape=(,), minval=, maxval=, dtype='int32')
变量(用来存储网络权重的)
tf.Variable(m)  # m代表矩阵,可以是numpy类型,也可以是张量
# 此类型具有的一些改变的方法
# 1
.assign(value)  # 重新设置值,注意:这里的value的shape要和之前的m一致
.assign_add(incre)  # 增量incre,注意:这里的incre的shape要和之前的m一致
.assign_sub(decre)  # 减量decre,注意:这里的decre的shape要和之前的m一致
一些数值计算方法
tf.square(m)  # 将矩阵m内元素进行平方
tf.exp(m)  # m里边元素i进行e的i次方计算
数据切分
# 一般都是从 csv或者excel获取数据
# 切分
dataset = tf.data.Dataset.from_tensor_slices((x,y)) # x,y使用numpy格式就好
# 打乱
dataset = dataset.shuffle(buffer_size=buffer_size).batch(batch_size)
使用继承设计自己想要的层(keras.layers.Layer)
# build(),call() 方法的使用

# 初始化器
tf.random_normal_initializer()  # 在add_weight()参数中initializer="random_normal"
# 查看权重
.weights  # 使用这个获取权重
示例:
# 需要继承的父类是 keras.layers.Layer
# 先看初级版本的,比较麻烦,而后面的有固定需要的方法能够更方便去使用
class Linear(keras.layers.Layer):
    """
     一般全连接层:y = x.w + b
    """ 
    def __init__(self, units=32, input_dim=32):
        super(Linear, self).__init__()
        
        init_w = tf.random_normal_initializer()  # 初始化器
        self.w = tf.Variable(init_w(shape=(input_dim, units),dtype='float32'),
                       trainable=True)
        init_b = tf.zeros_initializer()  # 初始化器
        self.b = tf.Variable(init_b(shape=(units, ), dtype='float32'), 
                        trainable=True)
        
    def call(self, inputs):
        return tf.matmul(x, self.w) + self.b

# 使用add_weight(),在build方法中(自动调用)
class Linear(keras.layers.Layer):
    def __init__(self, units):
        super(Linear, self).__init__()
        self.units = units
        
    def build(self, input_shape):
        """
        这里设置各种参数,在使用这个类的时候就会自动执行build。
        """
        self.w = self.add_weight(
        	shape=(input_shape[-1], self.units)
        	initializer='random_normal',
        	trainable=True,	
        )
        self.b = self.add_weight(
        	shape=(self.units, )
        	initializer='random_normal',
        	trainable=True,	
        )
    def call(self, inputs):
        return tf.matmul(inputs, self.w) + self.b  # 最终层的话返回的是 y_pre
##### 可能会注意到权重参数里有trainable,设置为True的时候是可以权重更迭的,否则对应权重不参与训练
计算loss(tf.keras.losses.xxxx)
# 损失函数也有API  loss_function
# 这是多分类交叉熵
loss_fn = tf.keras.losses.SparseCategooricalCrossentropy(from_logits=True) 

# 进行计算
loss = loss_fn(y, y_pre)
计算准确度等内置指标(tf.keras.metrics.xxxx)
# 举例选用metric = tf.keras.metrics.AUC()
"""
主要使用的方法有三种:
1、metric.update_state(y, y_pre)
2、metric.result()  # 获取值
3、metric.reset_state()  # 重新开始一个epoch之前进行重置
"""
动手重新想要的指标(keras.metric.Metric)
class F1Score(keras.metric.Metric):
	def __init(self, name='f1_score', dtype='float32', threshold=0.5, **kwargs):
        super().__init__(name=name, dtype=dtype, **kwargs)
        self.threshold = threshold
        self.true_positives = self.add_weight(
        	name='tp', dtype=dtype, initializer='zeros'	
        )
        self.false_positives = self.add_weight(
        	name='fp', dtype=dtype, initializer='zeros'	
        )
        self.false_negative = self.add_weight(
        	name='fn', dtype=dtype, initializer='zeros'	
        )
        
    def update_state(self, y_true, y_pre, sample_weight=None):
        """先转换成bool进行计算"""
        y_pre = tf.math.greater_equal(y_pre, self.threshold)
        y_true = tf.cast(y_true, tf.bool)
        y_pre = tf.cast(y_pre, tf.bool)  
        """再换成float进行求和"""
        tp_ = tf.cast(y_true & y_pre, self.dtype)
        fp_ = tf.cast(~y_true & y_pre, self.dtype)
        fn_ = tf.cast(y_true & ~y_pre, self.dtype)
        if sample_weight is not None:
            sample_weight = tf.cast(sample_weight, self.dtype)
            tp_ *= sample_weight
            fp_ *= sample_weight
            fn_ *= sample_weigh
        """求和"""
        self.true_positives.assign_add(tf.reduce_sum(tp_))
        self.false_positives.assign_add(tf.reduce_sum(fp_))
        self.false_negatives.assign_add(tf.reduce_sum(fn_))
        
    def result(self):
        precision = self.true_positives / (self.true_positives + self.false_positives)
        recall = self.true_positives / (self.true_positives + self.false_negatives)
        return precision * recall * 2.0 / (precision + recall)
计算梯度(谁对谁求导) 正向求梯度
# keras 其实非常方便的帮助我们做好了这个api
# 以下代码视为:当一个式子建立完成,我们就能够知道他的梯度
with tf.GradientTape() as Tape:
    # Tape.watch(x)       
    # 上方需要注意,当使用的x不是tf.Variable()的时候,需要进行对x的watch 
    y_pre = linear_layer(x)
    
    loss = loss_fn(y, y_pre)

#dy = Tape.gradient(y, x)  # y对x求导
dL = Tape.gradient(loss, Linear_layer.trainable_weights)
反向更新参数 优化器介绍
# 更新的时候都是利用梯度下降调整,步长等内容就和优化器有关
optimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)  # 这要在训练前都准备就绪的
Gradient decent
# 更新参数
optimizer.apply_gradients(zip(dL, Linear_layer.trainable_weights))
多层神经网络
# 堆叠起来就好,使用方式一样,都是同一个父类的

class multi_Layers(keras.layers.Layer):
    """简单堆叠起来"""
    
    def __init__(self):
        super(multi_Layers, self).__init__()
        self.Dense1 = Linear(32)
        self.Dense2 = Linear(32)
        self.Dense3 = Linear(10)
        
    def call(self, inputs):
        x = self.Dense1(inputs)
        x = tf.nn.relu(x)
        x = self.Dense2(x)
        x = tf.nn.relu(x)
        return self.Dense3(x)
add_loss()
# 这个方法会在loss中加上,这个方法只会在最后一次前向传播的时候使用,不会重复堆叠
# 也是使用sublayer
class ActivityRegularization(keras.layers.Layer):
    
    def __init__(self, rate=1e-2):
        super(ActivityRegularzation, self).__init__()
        self.rate = rate
        
    def call(self, inputs):
        self.add_loss(self.rate * tf.reduce_sum(inputs))  # 将维求和
        return inputs  # 原型返回
Make it fast
@tf.function
def train_on_batch(x, y):
    with tf.GradientTape() as tape:
        logits = model(x)
        loss = loss_fn(y, logits)
        gradients = tape.gradient(loss, model.trainable_weights)
    optimizer.apply_gradients(zip(gradients, model.trainable_weights))
    return loss
定义Dropout层
class Dropout(keras.layers.Layer):
    def __init__(self, rate):
        super(Dropout, self).__init__()
        self.rate = rate
    def call(self, inputs, training=None):
        if training:
            return tf.nn.dropout(inputs, rate=self.rate)
        return inputs

自己定义网络在研究中十分有用,而keras中也提供了许多可以用的API,直接使用效率更高一些。

API 大致套路是
# 设置层
inputs = tf.keras.Input(shape=(input_dim, ), dtype='float32')
x = Dense(units)(inputs)
# ...(一堆层)
outputs = Dense(units)(x)
# 实例化模型
model = tf.keras.Model(inputs, outputs)
# 模型编译
model.compile(
	loss=keras.losses.SparseCategoricalCrossentropy(
    	from_logits=True),
    optimizer=keras.optimizers.Adam(learning_rate=1e-3),
    metrics=[keras.metrics.SparseCategoricalAccuracy()],	
)
model.fit(dataset, epochs=n_epoch)
自定义model
class CustomModel(keras.Model):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.loss_tracker = keras.metrics.Mean(name="loss")
        self.accuracy = keras.metrics.SparseCategoricalAccuracy()
        self.loss_fn = 
keras.losses.SparseCategoricalCrossentropy(from_logits=True)
        self.optimizer = keras.optimizers.Adam(learning_rate=1e-3)
        
    def train_step(self, data):
        x, y = data
        with tf.GradientTape() as tape:
            y_pred = self(x, training=True) 
            loss = self.loss_fn(y, y_pred)
        gradients = tape.gradient(loss, self.trainable_weights)
        self.optimizer.apply_gradients(zip(gradients, self.trainable_weights))
        self.loss_tracker.update_state(loss)
        self.accuracy.update_state(y, y_pred)
        return {"loss": self.loss_tracker.result(), "accuracy": 
self.accuracy.result()}
    
    @property
    def metrics(self):
        return [self.loss_tracker, self.accuracy]
  • Tips:更多内容在官方API文档中更加详细,有了上面的知识铺垫,看文档就简单多了。
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/339799.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号