tensorflow2------自定义损失函数和Layer

import matplotlib as mpl #画图用的库
import matplotlib.pyplot as plt
#下面这一句是为了可以在notebook中画图
%matplotlib inline
import numpy as np
import sklearn   #机器学习算法库
import pandas as pd #处理数据的库   
import os
import sys
import time
import tensorflow as tf

from tensorflow import keras   #使用tensorflow中的keras
#import keras #单纯的使用keras

print(tf.__version__)
print(sys.version_info)
for module in mpl, np, sklearn, pd, tf, keras:
    print(module.__name__, module.__version__)
layer = tf.keras.layers.Dense(10)#None表示不定长,input_shape所表示的意思就是 未知数量的样本,每个样本有5个输入单元
layer = tf.keras.layers.Dense(100, input_shape=[None,5])# input_shape只在第一层时才需要添加,不添加系统可自动推导出来
layer(tf.zeros([10,5]))#这里定义输入为10*5的矩阵,就是说有10个这样的样本



#Variables可打印出layer中的所有参数
# x*w + b
#layer.variables
#trainable_variables 打印可训练的参数 这一层有100个神经单元,上一层有5个输入,则总的参数为 5*100+100
layer.trainable_variables
#trainable_weights 打印可训练的权重
#layer.trainable_weights




[,
 ]
#查询layer相关使用
help(layer)
#引用位于sklearn数据集中的房价预测数据集
from sklearn.datasets import fetch_california_housing

housing = fetch_california_housing()
print(housing.DESCR) #数据集的描述
print(housing.data.shape) #相当于 x
print(housing.target.shape) #相当于 y
#用sklearn中专门用于划分训练集和测试集的方法
from sklearn.model_selection import train_test_split

#train_test_split默认将数据划分为3:1,我们可以通过修改test_size值来改变数据划分比例(默认0.25,即3:1)
#将总数乘以test_size就表示test测试集、valid验证集数量
#将数据集整体拆分为train_all和test数据集
x_train_all,x_test, y_train_all,y_test = train_test_split(housing.data, housing.target, random_state=7)
#将train_all数据集拆分为train训练集和valid验证集
x_train,x_valid, y_train,y_valid = train_test_split(x_train_all, y_train_all, random_state=11)

print(x_train_all.shape,y_train_all.shape)
print(x_test.shape, y_test.shape)
print(x_train.shape, y_train.shape)
print(x_valid.shape, y_valid.shape)




(15480, 8) (15480,)
(5160, 8) (5160,)
(11610, 8) (11610,)
(3870, 8) (3870,)
#训练数据归一化处理
# x = (x - u)/std  u为均值,std为方差
from sklearn.preprocessing import StandardScaler #使用sklearn中的StandardScaler实现训练数据归一化

scaler = StandardScaler()#初始化一个scaler对象
x_train_scaler = scaler.fit_transform(x_train)#x_train已经是二维数据了,无需astype转换
x_valid_scaler = scaler.transform(x_valid)
x_test_scaler  = scaler.transform(x_test)
#tf.nn.softplus: log(1+e^x)
#keras.layers.Lambda 对流经该层的数据做个变换,而这个变换本身没有什么需要学习的参数
customized_softplus=keras.layers.Lambda(lambda x : tf.nn.softplus(x))
print(customized_softplus([-10.,-5.,0.,5.,10.]))



tf.Tensor([4.5417706e-05 6.7153489e-03 6.9314718e-01 5.0067153e+00 1.0000046e+01], shape=(5,), dtype=float32)
#自定义损失函数
#这里的接口参数为      真实值,预测值
def customized_mse(y_true, y_pred):
    return tf.reduce_mean(tf.square(y_pred-y_true))


#自定义全连接层dense layer,定义一个子类CustomizedDenseLayer,继承于tf.keras.layers.Layer
#重载 __init__、build、call三个方法
class CustomizedDenseLayer(keras.layers.Layer):
    def __init__(self, units, activation=None, **kwargs):
        self.units = units
        self.activation = keras.layers.Activation(activation)
        super(CustomizedDenseLayer, self).__init__(**kwargs)

    def build(self,input_shape):
        """构建所需要的参数"""
        # x * w + b. input_shape=[None, a] w:[a,b] output_shape=[None,b]
        self.kernel=self.add_weight(name="kernel",
                                    shape=(input_shape[1],self.units),#input_shape中的第二个值,units表示神经单元数 
                                    initializer="uniform",#表示如何初始化这个参数矩阵的,uniform表示使用均匀分布来初始化
                                    trainable=True) #参数可训练
        self.bias=self.add_weight(name="bias",
                                  shape=(self.units, ),
                                  initializer="zeros",
                                  trainable=True)
        
    def call(self,x):
        """完成正向计算"""
        return self.activation(x @ self.kernel + self.bias)
        
#tf.keras.models.Sequential()建立模型
model = keras.models.Sequential([
    #keras.layers.Dense(30, activation="relu",input_shape=x_train.shape[1:]),
    #keras.layers.Dense(1),
    #使用自定义的layer来构建模型
    CustomizedDenseLayer(30, activation="relu",input_shape=x_train.shape[1:]),
    CustomizedDenseLayer(1),
    customized_softplus,
    #keras.layers.Dense(1,activation="softplus"),
    #keras.layers.Dense(1),keras.layers.Activation("softplus"),
])
#编译model。 loss目标函数为均方差,这里表面上是字符串"mean_squared_error",实际上tensorflow中会映射到对应的算法函数,我们也可以自定义
model.compile(loss=customized_mse, optimizer="adam",metrics=["mean_squared_error"])
#查看model的架构
model.summary()



Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
customized_dense_layer (Cust (None, 30)                270       
_________________________________________________________________
customized_dense_layer_1 (Cu (None, 1)                 31        
_________________________________________________________________
lambda (Lambda)              (None, 1)                 0         
=================================================================
Total params: 301
Trainable params: 301
Non-trainable params: 0
#使用监听模型训练过程中的callbacks

logdir='./callbacks_regression'
if not os.path.exists(logdir):
    os.mkdir(logdir)
output_model_file = os.path.join(logdir,"regression_california_housing.h5")

#首先定义一个callback数组
callbacks = [
    #keras.callbacks.TensorBoard(logdir),
    #keras.callbacks.ModelCheckpoint(output_model_file,save_best_only=True),
    keras.callbacks.EarlyStopping(patience=5,min_delta=1e-3)
]

history=model.fit(x_train_scaler,y_train,epochs=100,
                 validation_data=(x_valid_scaler,y_valid),
                 callbacks=callbacks)



Train on 11610 samples, validate on 3870 samples
Epoch 1/100
11610/11610 [==============================] - 1s 97us/sample - loss: 1.3880 - mean_squared_error: 1.3880 - val_loss: 0.6174 - val_mean_squared_error: 0.6174
Epoch 2/100
11610/11610 [==============================] - 1s 64us/sample - loss: 0.4870 - mean_squared_error: 0.4870 - val_loss: 0.4603 - val_mean_squared_error: 0.4603
。。。
Epoch 42/100
11610/11610 [==============================] - 1s 63us/sample - loss: 0.3083 - mean_squared_error: 0.3083 - val_loss: 0.3200 - val_mean_squared_error: 0.3200
Epoch 43/100
11610/11610 [==============================] - 1s 62us/sample - loss: 0.3068 - mean_squared_error: 0.3068 - val_loss: 0.3203 - val_mean_squared_error: 0.3203
#打印模型训练过程中的相关曲线
def plot_learning_curves(history):
    pd.DataFrame(history.history).plot(figsize=(8,5))
    plt.grid(True)
    plt.gca().set_ylim(0,1)
    plt.show()
plot_learning_curves(history)

tensorflow2------自定义损失函数和Layer_第1张图片

model.evaluate(x_test_scaler,y_test)



5160/1 [================================。。。=============================================================================] - 0s 31us/sample - loss: 0.4490 - mean_squared_error: 0.3328
[0.3328484084255012, 0.33284846]

 

你可能感兴趣的:(#,tensorflow)