# encoding :utf-8 import tensorflow as tf from tensorflow import keras # 导入常见网络层, sequential容器, 优化器, 损失函数 from tensorflow.keras import layers, Sequential, optimizers, losses, metrics import os os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' import datetime import io import matplotlib.pyplot as plt # 1 """ x = tf.constant([2., 1., 0.1]) layer = layers.Softmax(axis=-1) # 创建softmax层 out = layer(x) # out = tf.nn.softmax(x) print(out) """ # 2 method one """ network = Sequential([ layers.Dense(3, activation=None), layers.ReLU(), layers.Dense(2, activation=None), layers.ReLU() ]) x = tf.random.normal([4, 3]) out = network(x) print(out) """ # 2 method two """ layers_num = 2 # 堆叠两次 network = Sequential([]) # 先创建空的网络容器 for _ in range(layers_num): network.add(layers.Dense(3)) # 添加全连接层 network.add(layers.ReLU()) network.build(input_shape=(4, 4)) # 创建网络参数 network.summary() for p in network.trainable_variables: print(p.name, p.shape) """ # 3 模型装配 # input data path = r'G:2019pythonmnist.npz' (x_train, y_train), (x_test, y_test) = tf.keras.datasets.mnist.load_data(path) x = tf.convert_to_tensor(x_train, dtype = tf.float32)/255. #0:1 ; -1:1(不适合训练,准确度不高) x = tf.reshape(x, [-1, 28*28]) y = tf.convert_to_tensor(y_train, dtype=tf.int32) y = tf.one_hot(y, depth=10) train_db = tf.data.Dataset.from_tensor_slices((x, y)) train_db = train_db.shuffle(60000) # 尽量与样本空间一样大 train_db = train_db.batch(100) # 128 def preprocess(x, y): x = tf.cast(x, dtype=tf.float32) / 255. #先将类型转化为float32,再归一到0-1 x = tf.reshape(x, [-1, 28*28]) #不知道x数量,用-1代替,转化为一维784个数据 y = tf.cast(y, dtype=tf.int32) #转化为整型32 y = tf.one_hot(y, depth=10) #训练数据所需的one-hot编码 return x, y # 将10000组测试数据预处理 test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test)) test_db = test_db.shuffle(10000) test_db = test_db.batch(100) #128 val_db = test_db.map(preprocess) """ # 用于4中调试用 network = Sequential([ layers.Dense(256, activation='relu'), layers.Dense(128, activation='relu'), layers.Dense(64, activation='relu'), layers.Dense(32, activation='relu'), layers.Dense(10) ]) network.build(input_shape=(4, 28*28)) network.summary() network.compile(optimizer=optimizers.Adam(lr=0.01), # Adam优化器 loss=losses.CategoricalCrossentropy(from_logits=True), # 交叉熵损失函数 metrics=['accuracy']) # 设定指标为准确率 # 3 模型训练 # 训练5个epochs,每2个epochs验证一次 fit()代表网络的训练过程 history = network.fit(train_db, epochs=5, validation_data=val_db, validation_freq=2) # history.history # 3 模型测试 x, y = next(iter(val_db)) # 加载一个测试数据 print('predict x:', x.shape) # 打印当前batch的形状 out = network.predict(x) # 模型预测保存在out中 print(out) # network.evaluate(val_db) # 模型测试,性能表现 # 4 模型的保存 # method 1 # network.save_weights('weight.ckpt') # print('saved weights.') # del network # method 2 # network.save('exam6_model.h5') # print('saved total model.') # del network # method 3 tf.saved_model.save(network, 'exam6_model-savedmodel') print('saving savedmodel.') del network """ # 创建相同的网络 有网络源的情况下 method 1 """ network = Sequential([ layers.Dense(256, activation='relu'), layers.Dense(128, activation='relu'), layers.Dense(64, activation='relu'), layers.Dense(32, activation='relu'), layers.Dense(10) ]) network.build(input_shape=(4, 28*28)) network.summary() network.compile(optimizer=optimizers.Adam(lr=0.01), # Adam优化器 loss=losses.CategoricalCrossentropy(from_logits=True), # 交叉熵损失函数 metrics=['accuracy']) # 设定指标为准确率 # 从文件中读入参数数据到当前网络 network.load_weights('weights.ckpt') print('loaded weights!') # Failed to find any matching files for weights.ckpt(import os !) """ # 无网络源的情况 method 2 # network = keras.models.load_model('exam6_model.h5') # network.summary() # SaveModel方式 method 3 """ print('load savedmodel from file.') network = tf.saved_model.load('exam6_model-savedmodel') acc_meter = metrics.CategoricalAccuracy() for x, y in val_db: pred = network(x) acc_meter.update_state(y_true=y, y_pred=pred) print("Test Accuracy:%f" % acc_meter.result()) # Test Accuracy:0.967000 """ # 5 自定义网络层 """ class MyDense(layers.Layer): def __init__(self, inp_dim, outp_dim): super(MyDense, self).__init__() # 创建权值张量并添加到管理列表中 self.kernel = self.add_variable('W', [inp_dim, outp_dim], trainable=True) # net = MyDense(4, 3) # print(net.variables, net.trainable_variables) def call(self, inputs, training=None): out = inputs@self.kernel out = tf.nn.relu(out) return out network = Sequential([ MyDense(784, 256), MyDense(256, 128), MyDense(128, 64), MyDense(64, 32), MyDense(32, 10) ]) network.build(input_shape=(None, 28*28)) network.summary() class MyModel(keras.Model): def __init__(self): super(MyModel, self).__init__() self.fc1 = MyDense(28*28, 256) self.fc2 = MyDense(256, 128) self.fc3 = MyDense(128, 64) self.fc4 = MyDense(64, 32) self.fc5 = MyDense(32, 10) def call(self, inputs, training=None): x = self.fc1(inputs) x = self.fc2(x) x = self.fc3(x) x = self.fc4(x) x = self.fc5(x) return x """ # 6 模型乐园 """ # 加载 ImageNet预训练模型,去掉最后一层 resnet = keras.applications.ResNet50(weights='imagenet', include_top=False) # resnet.summary() # x = tf.random.normal([4, 224, 224, 3]) # out = resnet(x) # print(out) # shape=(4, 7, 7, 2048) # 新建池化层 global_average_layer = layers.GlobalAveragePooling2D() # x = tf.random.normal([4, 7, 7, 2048]) # out = global_average_layer(x) # print(out.shape) # (4, 2048) # 新建全连接层 fc = layers.Dense(100) # x = tf.random.normal([4, 2048]) #out = fc(x) #print(out.shape) # (4, 100) # 重新包裹网络模型 mynet = Sequential([resnet, global_average_layer, fc]) mynet.summary() """ # 7 准确率 network = Sequential([ layers.Dense(256, activation='relu'), layers.Dense(128, activation='relu'), layers.Dense(64, activation='relu'), layers.Dense(32, activation='relu'), layers.Dense(10) ]) network.build(input_shape=(None, 28*28)) network.summary() optimizer=optimizers.Adam(lr=0.01) acc_meter = metrics.Accuracy() # 创建准确率测量器 loss_meter = metrics.Mean() # 新建平均测量器 for step, (x, y) in enumerate(train_db): #遍历切分好的数据step:0->599 with tf.GradientTape() as tape: out = network(x) loss = tf.reduce_mean(tf.losses.categorical_crossentropy(y, out, from_logits=True)) loss_meter.update_state(float(loss)) # 写入数据 grads = tape.gradient(loss, network.trainable_variables) optimizer.apply_gradients(zip(grads, network.trainable_variables)) if step % 100 == 0: print(step, 'loss:', loss_meter.result().numpy()) # 读统计数据 loss_meter.reset_states() # 清零 # 测试 if step % 500 == 0: total, total_correct = 0., 0 acc_meter.reset_states() for step, (x, y) in enumerate(val_db): out = network(x) correct = tf.equal(out, y) total_correct += tf.reduce_sum(tf.cast(correct, dtype=tf.int32)).numpy() total += x.shape[0] acc_meter.update_state(y, out) print(step, 'Evaluate Acc:', total_correct/total, acc_meter.result().numpy())
认识到keras用于神经网络学习的简便性!