Jackie Loong 6 年 前
コミット
65b368603e
14 ファイル変更1113 行追加0 行削除
  1. 100 0
      ch2/data.csv
  2. 70 0
      ch2/linear_regression.py
  3. 102 0
      ch3/forward.py
  4. 68 0
      ch3/main.py
  5. 152 0
      ch5/mnist_tensor.py
  6. 21 0
      ch5/nb.py
  7. 156 0
      ch6/auto_efficency_regression.py
  8. 129 0
      ch6/forward.py
  9. 67 0
      ch6/nb.py
  10. 25 0
      ch7/chain_rule.py
  11. 49 0
      ch7/himmelblau.py
  12. 11 0
      ch7/nb.py
  13. 127 0
      ch8/nb.py
  14. 36 0
      ch8/pretained.py

+ 100 - 0
ch2/data.csv

@@ -0,0 +1,100 @@
+32.502345269453031,31.70700584656992
+53.426804033275019,68.77759598163891
+61.530358025636438,62.562382297945803
+47.475639634786098,71.546632233567777
+59.813207869512318,87.230925133687393
+55.142188413943821,78.211518270799232
+52.211796692214001,79.64197304980874
+39.299566694317065,59.171489321869508
+48.10504169176825,75.331242297063056
+52.550014442733818,71.300879886850353
+45.419730144973755,55.165677145959123
+54.351634881228918,82.478846757497919
+44.164049496773352,62.008923245725825
+58.16847071685779,75.392870425994957
+56.727208057096611,81.43619215887864
+48.955888566093719,60.723602440673965
+44.687196231480904,82.892503731453715
+60.297326851333466,97.379896862166078
+45.618643772955828,48.847153317355072
+38.816817537445637,56.877213186268506
+66.189816606752601,83.878564664602763
+65.41605174513407,118.59121730252249
+47.48120860786787,57.251819462268969
+41.57564261748702,51.391744079832307
+51.84518690563943,75.380651665312357
+59.370822011089523,74.765564032151374
+57.31000343834809,95.455052922574737
+63.615561251453308,95.229366017555307
+46.737619407976972,79.052406169565586
+50.556760148547767,83.432071421323712
+52.223996085553047,63.358790317497878
+35.567830047746632,41.412885303700563
+42.436476944055642,76.617341280074044
+58.16454011019286,96.769566426108199
+57.504447615341789,74.084130116602523
+45.440530725319981,66.588144414228594
+61.89622268029126,77.768482417793024
+33.093831736163963,50.719588912312084
+36.436009511386871,62.124570818071781
+37.675654860850742,60.810246649902211
+44.555608383275356,52.682983366387781
+43.318282631865721,58.569824717692867
+50.073145632289034,82.905981485070512
+43.870612645218372,61.424709804339123
+62.997480747553091,115.24415280079529
+32.669043763467187,45.570588823376085
+40.166899008703702,54.084054796223612
+53.575077531673656,87.994452758110413
+33.864214971778239,52.725494375900425
+64.707138666121296,93.576118692658241
+38.119824026822805,80.166275447370964
+44.502538064645101,65.101711570560326
+40.599538384552318,65.562301260400375
+41.720676356341293,65.280886920822823
+51.088634678336796,73.434641546324301
+55.078095904923202,71.13972785861894
+41.377726534895203,79.102829683549857
+62.494697427269791,86.520538440347153
+49.203887540826003,84.742697807826218
+41.102685187349664,59.358850248624933
+41.182016105169822,61.684037524833627
+50.186389494880601,69.847604158249183
+52.378446219236217,86.098291205774103
+50.135485486286122,59.108839267699643
+33.644706006191782,69.89968164362763
+39.557901222906828,44.862490711164398
+56.130388816875467,85.498067778840223
+57.362052133238237,95.536686846467219
+60.269214393997906,70.251934419771587
+35.678093889410732,52.721734964774988
+31.588116998132829,50.392670135079896
+53.66093226167304,63.642398775657753
+46.682228649471917,72.247251068662365
+43.107820219102464,57.812512976181402
+70.34607561504933,104.25710158543822
+44.492855880854073,86.642020318822006
+57.50453330326841,91.486778000110135
+36.930076609191808,55.231660886212836
+55.805733357942742,79.550436678507609
+38.954769073377065,44.847124242467601
+56.901214702247074,80.207523139682763
+56.868900661384046,83.14274979204346
+34.33312470421609,55.723489260543914
+59.04974121466681,77.634182511677864
+57.788223993230673,99.051414841748269
+54.282328705967409,79.120646274680027
+51.088719898979143,69.588897851118475
+50.282836348230731,69.510503311494389
+44.211741752090113,73.687564318317285
+38.005488008060688,61.366904537240131
+32.940479942618296,67.170655768995118
+53.691639571070056,85.668203145001542
+68.76573426962166,114.85387123391394
+46.230966498310252,90.123572069967423
+68.319360818255362,97.919821035242848
+50.030174340312143,81.536990783015028
+49.239765342753763,72.111832469615663
+50.039575939875988,85.232007342325673
+48.149858891028863,66.224957888054632
+25.128484647772304,53.454394214850524

+ 70 - 0
ch2/linear_regression.py

@@ -0,0 +1,70 @@
+import numpy as np
+
+# data = []
+# for i in range(100):
+# 	x = np.random.uniform(3., 12.)
+# 	# mean=0, std=0.1
+# 	eps = np.random.normal(0., 0.1)
+# 	y = 1.477 * x + 0.089 + eps
+# 	data.append([x, y])
+# data = np.array(data)
+# print(data.shape, data)
+
+# y = wx + b
+def compute_error_for_line_given_points(b, w, points):
+    totalError = 0
+    for i in range(0, len(points)):
+        x = points[i, 0]
+        y = points[i, 1]
+        # computer mean-squared-error
+        totalError += (y - (w * x + b)) ** 2
+    # average loss for each point
+    return totalError / float(len(points))
+
+
+
+def step_gradient(b_current, w_current, points, learningRate):
+    b_gradient = 0
+    w_gradient = 0
+    N = float(len(points))
+    for i in range(0, len(points)):
+        x = points[i, 0]
+        y = points[i, 1]
+        # grad_b = 2(wx+b-y)
+        b_gradient += (2/N) * ((w_current * x + b_current) - y)
+        # grad_w = 2(wx+b-y)*x
+        w_gradient += (2/N) * x * ((w_current * x + b_current) - y)
+    # update w'
+    new_b = b_current - (learningRate * b_gradient)
+    new_w = w_current - (learningRate * w_gradient)
+    return [new_b, new_w]
+
+def gradient_descent_runner(points, starting_b, starting_w, learning_rate, num_iterations):
+    b = starting_b
+    w = starting_w
+    # update for several times
+    for i in range(num_iterations):
+        b, w = step_gradient(b, w, np.array(points), learning_rate)
+    return [b, w]
+
+
+def run():
+	
+    points = np.genfromtxt("data.csv", delimiter=",")
+    learning_rate = 0.0001
+    initial_b = 0 # initial y-intercept guess
+    initial_w = 0 # initial slope guess
+    num_iterations = 1000
+    print("Starting gradient descent at b = {0}, w = {1}, error = {2}"
+          .format(initial_b, initial_w,
+                  compute_error_for_line_given_points(initial_b, initial_w, points))
+          )
+    print("Running...")
+    [b, w] = gradient_descent_runner(points, initial_b, initial_w, learning_rate, num_iterations)
+    print("After {0} iterations b = {1}, w = {2}, error = {3}".
+          format(num_iterations, b, w,
+                 compute_error_for_line_given_points(b, w, points))
+          )
+
+if __name__ == '__main__':
+    run()

+ 102 - 0
ch3/forward.py

@@ -0,0 +1,102 @@
+import  matplotlib
+from 	matplotlib import pyplot as plt
+# Default parameters for plots
+matplotlib.rcParams['font.size'] = 20
+matplotlib.rcParams['figure.titlesize'] = 20
+matplotlib.rcParams['figure.figsize'] = [9, 7]
+matplotlib.rcParams['font.family'] = ['STKaiTi']
+matplotlib.rcParams['axes.unicode_minus']=False 
+
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import datasets
+import  os
+
+os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
+
+# x: [60k, 28, 28],
+# y: [60k]
+(x, y), _ = datasets.mnist.load_data()
+# x: [0~255] => [0~1.]
+x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
+y = tf.convert_to_tensor(y, dtype=tf.int32)
+
+print(x.shape, y.shape, x.dtype, y.dtype)
+print(tf.reduce_min(x), tf.reduce_max(x))
+print(tf.reduce_min(y), tf.reduce_max(y))
+
+
+train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128)
+train_iter = iter(train_db)
+sample = next(train_iter)
+print('batch:', sample[0].shape, sample[1].shape)
+
+
+# [b, 784] => [b, 256] => [b, 128] => [b, 10]
+# [dim_in, dim_out], [dim_out]
+w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
+b1 = tf.Variable(tf.zeros([256]))
+w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
+b2 = tf.Variable(tf.zeros([128]))
+w3 = tf.Variable(tf.random.truncated_normal([128, 10], stddev=0.1))
+b3 = tf.Variable(tf.zeros([10]))
+
+lr = 1e-3
+
+losses = []
+
+for epoch in range(20): # iterate db for 10
+    for step, (x, y) in enumerate(train_db): # for every batch
+        # x:[128, 28, 28]
+        # y: [128]
+
+        # [b, 28, 28] => [b, 28*28]
+        x = tf.reshape(x, [-1, 28*28])
+
+        with tf.GradientTape() as tape: # tf.Variable
+            # x: [b, 28*28]
+            # h1 = x@w1 + b1
+            # [b, 784]@[784, 256] + [256] => [b, 256] + [256] => [b, 256] + [b, 256]
+            h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 256])
+            h1 = tf.nn.relu(h1)
+            # [b, 256] => [b, 128]
+            h2 = h1@w2 + b2
+            h2 = tf.nn.relu(h2)
+            # [b, 128] => [b, 10]
+            out = h2@w3 + b3
+
+            # compute loss
+            # out: [b, 10]
+            # y: [b] => [b, 10]
+            y_onehot = tf.one_hot(y, depth=10)
+
+            # mse = mean(sum(y-out)^2)
+            # [b, 10]
+            loss = tf.square(y_onehot - out)
+            # mean: scalar
+            loss = tf.reduce_mean(loss)
+
+        # compute gradients
+        grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])
+        # print(grads)
+        # w1 = w1 - lr * w1_grad
+        w1.assign_sub(lr * grads[0])
+        b1.assign_sub(lr * grads[1])
+        w2.assign_sub(lr * grads[2])
+        b2.assign_sub(lr * grads[3])
+        w3.assign_sub(lr * grads[4])
+        b3.assign_sub(lr * grads[5])
+
+
+        if step % 100 == 0:
+            print(epoch, step, 'loss:', float(loss))
+
+    losses.append(float(loss))
+
+plt.figure()
+plt.plot(losses, color='C0', marker='s', label='训练')
+plt.xlabel('Epoch')
+plt.legend()
+plt.ylabel('MSE')
+plt.savefig('forward.svg')
+# plt.show()

+ 68 - 0
ch3/main.py

@@ -0,0 +1,68 @@
+import  os
+os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
+
+
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import layers, optimizers, datasets
+
+
+
+
+(x, y), (x_val, y_val) = datasets.mnist.load_data() 
+x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
+y = tf.convert_to_tensor(y, dtype=tf.int32)
+y = tf.one_hot(y, depth=10)
+print(x.shape, y.shape)
+train_dataset = tf.data.Dataset.from_tensor_slices((x, y))
+train_dataset = train_dataset.batch(200)
+
+ 
+
+
+model = keras.Sequential([ 
+    layers.Dense(512, activation='relu'),
+    layers.Dense(256, activation='relu'),
+    layers.Dense(10)])
+
+optimizer = optimizers.SGD(learning_rate=0.001)
+
+
+def train_epoch(epoch):
+
+    # Step4.loop
+    for step, (x, y) in enumerate(train_dataset):
+
+
+        with tf.GradientTape() as tape:
+            # [b, 28, 28] => [b, 784]
+            x = tf.reshape(x, (-1, 28*28))
+            # Step1. compute output
+            # [b, 784] => [b, 10]
+            out = model(x)
+            # Step2. compute loss
+            loss = tf.reduce_sum(tf.square(out - y)) / x.shape[0]
+
+        # Step3. optimize and update w1, w2, w3, b1, b2, b3
+        grads = tape.gradient(loss, model.trainable_variables)
+        # w' = w - lr * grad
+        optimizer.apply_gradients(zip(grads, model.trainable_variables))
+
+        if step % 100 == 0:
+            print(epoch, step, 'loss:', loss.numpy())
+
+
+
+def train():
+
+    for epoch in range(30):
+
+        train_epoch(epoch)
+
+
+
+
+
+
+if __name__ == '__main__':
+    train()

+ 152 - 0
ch5/mnist_tensor.py

@@ -0,0 +1,152 @@
+#%%
+import  matplotlib
+from    matplotlib import pyplot as plt
+# Default parameters for plots
+matplotlib.rcParams['font.size'] = 20
+matplotlib.rcParams['figure.titlesize'] = 20
+matplotlib.rcParams['figure.figsize'] = [9, 7]
+matplotlib.rcParams['font.family'] = ['STKaiTi']
+matplotlib.rcParams['axes.unicode_minus']=False 
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import datasets, layers, optimizers
+import  os
+
+
+
+
+
+os.environ['TF_CPP_MIN_LOG_LEVEL']='2'
+print(tf.__version__)
+
+
+def preprocess(x, y): 
+    # [b, 28, 28], [b]
+    print(x.shape,y.shape)
+    x = tf.cast(x, dtype=tf.float32) / 255.
+    x = tf.reshape(x, [-1, 28*28])
+    y = tf.cast(y, dtype=tf.int32)
+    y = tf.one_hot(y, depth=10)
+
+    return x,y
+
+#%%
+(x, y), (x_test, y_test) = datasets.mnist.load_data()
+print('x:', x.shape, 'y:', y.shape, 'x test:', x_test.shape, 'y test:', y_test)
+#%%
+batchsz = 512
+train_db = tf.data.Dataset.from_tensor_slices((x, y))
+train_db = train_db.shuffle(1000)
+train_db = train_db.batch(batchsz)
+train_db = train_db.map(preprocess)
+train_db = train_db.repeat(20)
+
+#%%
+
+test_db = tf.data.Dataset.from_tensor_slices((x_test, y_test))
+test_db = test_db.shuffle(1000).batch(batchsz).map(preprocess)
+x,y = next(iter(train_db))
+print('train sample:', x.shape, y.shape)
+# print(x[0], y[0])
+
+
+
+
+#%%
+def main():
+
+    # learning rate
+    lr = 1e-2
+    accs,losses = [], []
+
+
+    # 784 => 512
+    w1, b1 = tf.Variable(tf.random.normal([784, 256], stddev=0.1)), tf.Variable(tf.zeros([256]))
+    # 512 => 256
+    w2, b2 = tf.Variable(tf.random.normal([256, 128], stddev=0.1)), tf.Variable(tf.zeros([128]))
+    # 256 => 10
+    w3, b3 = tf.Variable(tf.random.normal([128, 10], stddev=0.1)), tf.Variable(tf.zeros([10]))
+
+
+
+ 
+
+    for step, (x,y) in enumerate(train_db):
+ 
+        # [b, 28, 28] => [b, 784]
+        x = tf.reshape(x, (-1, 784))
+
+        with tf.GradientTape() as tape:
+
+            # layer1.
+            h1 = x @ w1 + b1
+            h1 = tf.nn.relu(h1)
+            # layer2
+            h2 = h1 @ w2 + b2
+            h2 = tf.nn.relu(h2)
+            # output
+            out = h2 @ w3 + b3
+            # out = tf.nn.relu(out)
+
+            # compute loss
+            # [b, 10] - [b, 10]
+            loss = tf.square(y-out)
+            # [b, 10] => scalar
+            loss = tf.reduce_mean(loss)
+
+ 
+        grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3]) 
+        for p, g in zip([w1, b1, w2, b2, w3, b3], grads):
+            p.assign_sub(lr * g)
+
+
+        # print
+        if step % 80 == 0:
+            print(step, 'loss:', float(loss))
+            losses.append(float(loss))
+ 
+        if step %80 == 0:
+            # evaluate/test
+            total, total_correct = 0., 0
+
+            for x, y in test_db:
+                # layer1.
+                h1 = x @ w1 + b1
+                h1 = tf.nn.relu(h1)
+                # layer2
+                h2 = h1 @ w2 + b2
+                h2 = tf.nn.relu(h2)
+                # output
+                out = h2 @ w3 + b3
+                # [b, 10] => [b]
+                pred = tf.argmax(out, axis=1)
+                # convert one_hot y to number y
+                y = tf.argmax(y, axis=1)
+                # bool type
+                correct = tf.equal(pred, y)
+                # bool tensor => int tensor => numpy
+                total_correct += tf.reduce_sum(tf.cast(correct, dtype=tf.int32)).numpy()
+                total += x.shape[0]
+
+            print(step, 'Evaluate Acc:', total_correct/total)
+
+            accs.append(total_correct/total)
+
+
+    plt.figure()
+    x = [i*80 for i in range(len(losses))]
+    plt.plot(x, losses, color='C0', marker='s', label='训练')
+    plt.ylabel('MSE')
+    plt.xlabel('Step')
+    plt.legend()
+    plt.savefig('train.svg')
+
+    plt.figure()
+    plt.plot(x, accs, color='C1', marker='s', label='测试')
+    plt.ylabel('准确率')
+    plt.xlabel('Step')
+    plt.legend()
+    plt.savefig('test.svg')
+
+if __name__ == '__main__':
+    main()

+ 21 - 0
ch5/nb.py

@@ -0,0 +1,21 @@
+#%%
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import datasets
+import  os
+
+
+#%%
+a = tf.random.normal([4,35,8]) # 模拟成绩册A
+b = tf.random.normal([6,35,8]) # 模拟成绩册B
+tf.concat([a,b],axis=0) # 合并成绩册
+
+
+#%%
+x = tf.random.normal([2,784])
+w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
+b1 = tf.Variable(tf.zeros([256]))
+o1 = tf.matmul(x,w1) + b1  #
+o1 = tf.nn.relu(o1)
+
+#%%

+ 156 - 0
ch6/auto_efficency_regression.py

@@ -0,0 +1,156 @@
+#%%
+from __future__ import absolute_import, division, print_function, unicode_literals
+
+import pathlib
+import os
+import matplotlib.pyplot as plt
+import pandas as pd
+import seaborn as sns
+ 
+import tensorflow as tf
+
+from tensorflow import keras
+from tensorflow.keras import layers, losses
+
+print(tf.__version__)
+os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
+
+
+# 在线下载汽车效能数据集
+dataset_path = keras.utils.get_file("auto-mpg.data", "http://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data")
+
+# 效能(公里数每加仑),气缸数,排量,马力,重量
+# 加速度,型号年份,产地
+column_names = ['MPG','Cylinders','Displacement','Horsepower','Weight',
+                'Acceleration', 'Model Year', 'Origin']
+raw_dataset = pd.read_csv(dataset_path, names=column_names,
+                      na_values = "?", comment='\t',
+                      sep=" ", skipinitialspace=True)
+
+dataset = raw_dataset.copy()
+# 查看部分数据
+dataset.tail()
+dataset.head()
+dataset
+#%%
+
+
+#%%
+
+# 统计空白数据,并清除
+dataset.isna().sum()
+dataset = dataset.dropna()
+dataset.isna().sum()
+dataset
+#%%
+
+# 处理类别型数据,其中origin列代表了类别1,2,3,分布代表产地:美国、欧洲、日本
+# 其弹出这一列
+origin = dataset.pop('Origin')
+# 根据origin列来写入新列
+dataset['USA'] = (origin == 1)*1.0
+dataset['Europe'] = (origin == 2)*1.0
+dataset['Japan'] = (origin == 3)*1.0
+dataset.tail()
+
+
+# 切分为训练集和测试集
+train_dataset = dataset.sample(frac=0.8,random_state=0)
+test_dataset = dataset.drop(train_dataset.index) 
+
+
+#%% 统计数据
+sns.pairplot(train_dataset[["Cylinders", "Displacement", "Weight", "MPG"]], 
+diag_kind="kde")
+#%%
+# 查看训练集的输入X的统计数据
+train_stats = train_dataset.describe()
+train_stats.pop("MPG")
+train_stats = train_stats.transpose()
+train_stats
+
+
+# 移动MPG油耗效能这一列为真实标签Y
+train_labels = train_dataset.pop('MPG')
+test_labels = test_dataset.pop('MPG')
+
+
+# 标准化数据
+def norm(x):
+  return (x - train_stats['mean']) / train_stats['std']
+normed_train_data = norm(train_dataset)
+normed_test_data = norm(test_dataset)
+#%%
+
+print(normed_train_data.shape,train_labels.shape)
+print(normed_test_data.shape, test_labels.shape)
+#%%
+
+class Network(keras.Model):
+    # 回归网络
+    def __init__(self):
+        super(Network, self).__init__()
+        # 创建3个全连接层
+        self.fc1 = layers.Dense(64, activation='relu')
+        self.fc2 = layers.Dense(64, activation='relu')
+        self.fc3 = layers.Dense(1)
+
+    def call(self, inputs, training=None, mask=None):
+        # 依次通过3个全连接层
+        x = self.fc1(inputs)
+        x = self.fc2(x)
+        x = self.fc3(x)
+
+        return x
+
+model = Network()
+model.build(input_shape=(None, 9))
+model.summary()
+optimizer = tf.keras.optimizers.RMSprop(0.001)
+train_db = tf.data.Dataset.from_tensor_slices((normed_train_data.values, train_labels.values))
+train_db = train_db.shuffle(100).batch(32)
+
+# # 未训练时测试
+# example_batch = normed_train_data[:10]
+# example_result = model.predict(example_batch)
+# example_result
+
+
+train_mae_losses = []
+test_mae_losses = []
+for epoch in range(200):
+    for step, (x,y) in enumerate(train_db):
+
+        with tf.GradientTape() as tape:
+            out = model(x)
+            loss = tf.reduce_mean(losses.MSE(y, out))
+            mae_loss = tf.reduce_mean(losses.MAE(y, out)) 
+
+        if step % 10 == 0:
+            print(epoch, step, float(loss))
+
+        grads = tape.gradient(loss, model.trainable_variables)
+        optimizer.apply_gradients(zip(grads, model.trainable_variables))
+
+    train_mae_losses.append(float(mae_loss))
+    out = model(tf.constant(normed_test_data.values))
+    test_mae_losses.append(tf.reduce_mean(losses.MAE(test_labels, out)))
+
+
+plt.figure()
+plt.xlabel('Epoch')
+plt.ylabel('MAE')
+plt.plot(train_mae_losses,  label='Train')
+
+plt.plot(test_mae_losses, label='Test')
+plt.legend()
+ 
+# plt.ylim([0,10])
+plt.legend()
+plt.savefig('auto.svg')
+plt.show() 
+
+
+
+
+#%%

+ 129 - 0
ch6/forward.py

@@ -0,0 +1,129 @@
+#%%
+
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import layers
+from    tensorflow.keras import datasets
+import  os
+
+
+#%% 
+x = tf.random.normal([2,28*28])
+w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
+b1 = tf.Variable(tf.zeros([256]))
+o1 = tf.matmul(x,w1) + b1
+o1
+#%%
+x = tf.random.normal([4,28*28])
+fc1 = layers.Dense(256, activation=tf.nn.relu) 
+fc2 = layers.Dense(128, activation=tf.nn.relu) 
+fc3 = layers.Dense(64, activation=tf.nn.relu) 
+fc4 = layers.Dense(10, activation=None) 
+h1 = fc1(x)
+h2 = fc2(h1)
+h3 = fc3(h2)
+h4 = fc4(h3)
+
+model = layers.Sequential([
+    layers.Dense(256, activation=tf.nn.relu) ,
+    layers.Dense(128, activation=tf.nn.relu) ,
+    layers.Dense(64, activation=tf.nn.relu) ,
+    layers.Dense(10, activation=None) ,
+])
+out = model(x)
+
+#%%
+256*784+256+128*256+128+64*128+64+10*64+10
+#%%
+os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
+
+# x: [60k, 28, 28],
+# y: [60k]
+(x, y), _ = datasets.mnist.load_data()
+# x: [0~255] => [0~1.]
+x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
+y = tf.convert_to_tensor(y, dtype=tf.int32)
+
+print(x.shape, y.shape, x.dtype, y.dtype)
+print(tf.reduce_min(x), tf.reduce_max(x))
+print(tf.reduce_min(y), tf.reduce_max(y))
+
+
+train_db = tf.data.Dataset.from_tensor_slices((x,y)).batch(128)
+train_iter = iter(train_db)
+sample = next(train_iter)
+print('batch:', sample[0].shape, sample[1].shape)
+
+
+# [b, 784] => [b, 256] => [b, 128] => [b, 10]
+# [dim_in, dim_out], [dim_out]
+# 隐藏层1张量
+w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
+b1 = tf.Variable(tf.zeros([256]))
+# 隐藏层2张量
+w2 = tf.Variable(tf.random.truncated_normal([256, 128], stddev=0.1))
+b2 = tf.Variable(tf.zeros([128]))
+# 隐藏层3张量
+w3 = tf.Variable(tf.random.truncated_normal([128, 64], stddev=0.1))
+b3 = tf.Variable(tf.zeros([64]))
+# 输出层张量
+w4 = tf.Variable(tf.random.truncated_normal([64, 10], stddev=0.1))
+b4 = tf.Variable(tf.zeros([10]))
+
+lr = 1e-3
+
+for epoch in range(10): # iterate db for 10
+    for step, (x, y) in enumerate(train_db): # for every batch
+        # x:[128, 28, 28]
+        # y: [128]
+
+        # [b, 28, 28] => [b, 28*28]
+        x = tf.reshape(x, [-1, 28*28])
+
+        with tf.GradientTape() as tape: # tf.Variable
+            # x: [b, 28*28]
+            #  隐藏层1前向计算,[b, 28*28] => [b, 256]
+            h1 = x@w1 + tf.broadcast_to(b1, [x.shape[0], 256])
+            h1 = tf.nn.relu(h1)
+            # 隐藏层2前向计算,[b, 256] => [b, 128]
+            h2 = h1@w2 + b2
+            h2 = tf.nn.relu(h2)
+            # 隐藏层3前向计算,[b, 128] => [b, 64] 
+            h3 = h2@w3 + b3
+            h3 = tf.nn.relu(h3)
+            # 输出层前向计算,[b, 64] => [b, 10] 
+            h4 = h3@w4 + b4
+            out = h4
+
+            # compute loss
+            # out: [b, 10]
+            # y: [b] => [b, 10]
+            y_onehot = tf.one_hot(y, depth=10)
+
+            # mse = mean(sum(y-out)^2)
+            # [b, 10]
+            loss = tf.square(y_onehot - out)
+            # mean: scalar
+            loss = tf.reduce_mean(loss)
+
+        # compute gradients
+        grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3, w4, b4])
+        # print(grads)
+        # w1 = w1 - lr * w1_grad
+        w1.assign_sub(lr * grads[0])
+        b1.assign_sub(lr * grads[1])
+        w2.assign_sub(lr * grads[2])
+        b2.assign_sub(lr * grads[3])
+        w3.assign_sub(lr * grads[4])
+        b3.assign_sub(lr * grads[5])
+        w4.assign_sub(lr * grads[6])
+        b4.assign_sub(lr * grads[7])
+
+
+        if step % 100 == 0:
+            print(epoch, step, 'loss:', float(loss))
+
+
+
+
+#%%

+ 67 - 0
ch6/nb.py

@@ -0,0 +1,67 @@
+#%%
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import datasets, layers
+import  os
+
+
+#%%
+a = tf.random.normal([4,35,8]) # 模拟成绩册A
+b = tf.random.normal([6,35,8]) # 模拟成绩册B
+tf.concat([a,b],axis=0) # 合并成绩册
+
+
+#%%
+x = tf.random.normal([2,784])
+w1 = tf.Variable(tf.random.truncated_normal([784, 256], stddev=0.1))
+b1 = tf.Variable(tf.zeros([256]))
+o1 = tf.matmul(x,w1) + b1  #
+o1 = tf.nn.relu(o1)
+o1
+#%%
+x = tf.random.normal([4,28*28])
+# 创建全连接层,指定输出节点数和激活函数
+fc = layers.Dense(512, activation=tf.nn.relu) 
+h1 = fc(x)  # 通过fc类完成一次全连接层的计算
+
+
+#%%
+vars(fc)
+
+#%%
+x = tf.random.normal([4,4])
+# 创建全连接层,指定输出节点数和激活函数
+fc = layers.Dense(3, activation=tf.nn.relu) 
+h1 = fc(x)  # 通过fc类完成一次全连接层的计算
+
+
+#%%
+fc.non_trainable_variables
+
+#%%
+embedding = layers.Embedding(10000, 100)
+
+#%%
+x = tf.ones([25000,80])
+
+#%%
+
+embedding(x)
+
+#%%
+z = tf.random.normal([2,10]) # 构造输出层的输出
+y_onehot = tf.constant([1,3]) # 构造真实值
+y_onehot = tf.one_hot(y_onehot, depth=10) # one-hot编码
+# 输出层未使用Softmax函数,故from_logits设置为True
+loss = keras.losses.categorical_crossentropy(y_onehot,z,from_logits=True)
+loss = tf.reduce_mean(loss) # 计算平均交叉熵损失
+loss
+
+
+#%%
+criteon = keras.losses.CategoricalCrossentropy(from_logits=True)
+loss = criteon(y_onehot,z) # 计算损失
+loss
+
+
+#%%

+ 25 - 0
ch7/chain_rule.py

@@ -0,0 +1,25 @@
+import tensorflow as tf 
+
+# 构建待优化变量
+x = tf.constant(1.)
+w1 = tf.constant(2.)
+b1 = tf.constant(1.)
+w2 = tf.constant(2.)
+b2 = tf.constant(1.)
+
+
+with tf.GradientTape(persistent=True) as tape:
+	# 非tf.Variable类型的张量需要人为设置记录梯度信息
+	tape.watch([w1, b1, w2, b2])
+	# 构建2层网络
+	y1 = x * w1 + b1	
+	y2 = y1 * w2 + b2
+
+# 独立求解出各个导数
+dy2_dy1 = tape.gradient(y2, [y1])[0]
+dy1_dw1 = tape.gradient(y1, [w1])[0]
+dy2_dw1 = tape.gradient(y2, [w1])[0]
+
+# 验证链式法则
+print(dy2_dy1 * dy1_dw1)
+print(dy2_dw1)

+ 49 - 0
ch7/himmelblau.py

@@ -0,0 +1,49 @@
+import  numpy as np
+from    mpl_toolkits.mplot3d import Axes3D
+from    matplotlib import pyplot as plt
+import  tensorflow as tf
+
+
+
+def himmelblau(x):
+    # himmelblau函数实现
+    return (x[0] ** 2 + x[1] - 11) ** 2 + (x[0] + x[1] ** 2 - 7) ** 2
+
+
+x = np.arange(-6, 6, 0.1)
+y = np.arange(-6, 6, 0.1)
+print('x,y range:', x.shape, y.shape)
+# 生成x-y平面采样网格点,方便可视化
+X, Y = np.meshgrid(x, y)
+print('X,Y maps:', X.shape, Y.shape)
+Z = himmelblau([X, Y]) # 计算网格点上的函数值
+
+# 绘制himmelblau函数曲面
+fig = plt.figure('himmelblau')
+ax = fig.gca(projection='3d')
+ax.plot_surface(X, Y, Z)
+ax.view_init(60, -30)
+ax.set_xlabel('x')
+ax.set_ylabel('y')
+plt.show()
+
+# 参数的初始化值对优化的影响不容忽视,可以通过尝试不同的初始化值,
+# 检验函数优化的极小值情况
+# [1., 0.], [-4, 0.], [4, 0.]
+# x = tf.constant([4., 0.])
+# x = tf.constant([1., 0.])
+# x = tf.constant([-4., 0.])
+x = tf.constant([-2., 2.])
+
+for step in range(200):# 循环优化
+    with tf.GradientTape() as tape: #梯度跟踪
+        tape.watch([x]) # 记录梯度
+        y = himmelblau(x) # 前向传播
+    # 反向传播
+    grads = tape.gradient(y, [x])[0] 
+    # 更新参数,0.01为学习率
+    x -= 0.01*grads
+    # 打印优化的极小值
+    if step % 20 == 19:
+        print ('step {}: x = {}, f(x) = {}'
+               .format(step, x.numpy(), y.numpy()))

+ 11 - 0
ch7/nb.py

@@ -0,0 +1,11 @@
+#%%
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import datasets, layers
+
+#%%
+def sigmoid(x): # sigmoid函数,也可以直接使用tf.nn.sigmoid
+    return 1 / (1 + tf.math.exp(-x))
+
+def derivative(x): # sigmoid导数的计算
+    return sigmoid(x)*(1-sigmoid(x))

+ 127 - 0
ch8/nb.py

@@ -0,0 +1,127 @@
+#%%
+import tensorflow as tf
+from tensorflow import keras
+from tensorflow.keras import layers,Sequential,losses,optimizers,datasets
+
+
+#%%
+x = tf.constant([2.,1.,0.1])
+layer = layers.Softmax(axis=-1)
+layer(x)
+#%%
+def proprocess(x,y):
+    x = tf.reshape(x, [-1]) 
+    return x,y
+
+# x: [60k, 28, 28],
+# y: [60k]
+(x, y), (x_test,y_test) = datasets.mnist.load_data()
+# x: [0~255] => [0~1.]
+x = tf.convert_to_tensor(x, dtype=tf.float32) / 255.
+y = tf.convert_to_tensor(y, dtype=tf.int32) 
+
+# x: [0~255] => [0~1.]
+x_test = tf.convert_to_tensor(x_test, dtype=tf.float32) / 255.
+y_test = tf.convert_to_tensor(y_test, dtype=tf.int32) 
+
+train_db = tf.data.Dataset.from_tensor_slices((x,y))
+train_db = train_db.shuffle(1000).map(proprocess).batch(128)
+
+val_db = tf.data.Dataset.from_tensor_slices((x_test,y_test))
+val_db = val_db.shuffle(1000).map(proprocess).batch(128)
+
+x,y = next(iter(train_db))
+print(x.shape, y.shape)
+#%%
+
+from tensorflow.keras import layers, Sequential
+network = Sequential([
+    layers.Dense(3, activation=None),
+    layers.ReLU(),
+    layers.Dense(2, activation=None),
+    layers.ReLU()
+])
+x = tf.random.normal([4,3])
+network(x)
+
+#%%
+layers_num = 2
+network = Sequential([])
+for _ in range(layers_num):
+    network.add(layers.Dense(3))
+    network.add(layers.ReLU())
+network.build(input_shape=(None, 4))
+network.summary()
+
+#%%
+for p in network.trainable_variables:
+    print(p.name, p.shape)
+
+#%%
+# 创建5层的全连接层网络
+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()
+
+
+#%%
+# 导入优化器,损失函数模块
+from tensorflow.keras import optimizers,losses 
+# 采用Adam优化器,学习率为0.01;采用交叉熵损失函数,包含Softmax
+network.compile(optimizer=optimizers.Adam(lr=0.01),
+        loss=losses.CategoricalCrossentropy(from_logits=True),
+        metrics=['accuracy'] # 设置测量指标为准确率
+)
+
+
+#%%
+# 指定训练集为db,验证集为val_db,训练5个epochs,每2个epoch验证一次
+history = network.fit(train_db, epochs=5, validation_data=val_db, validation_freq=2)
+
+
+#%%
+history.history # 打印训练记录
+
+#%%
+# 保存模型参数到文件上
+network.save_weights('weights.ckpt')
+print('saved weights.')
+del network # 删除网络对象
+# 重新创建相同的网络结构
+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.compile(optimizer=optimizers.Adam(lr=0.01),
+        loss=tf.losses.CategoricalCrossentropy(from_logits=True),
+        metrics=['accuracy']
+    ) 
+# 从参数文件中读取数据并写入当前网络
+network.load_weights('weights.ckpt')
+print('loaded weights!')
+
+
+#%%
+# 新建池化层
+global_average_layer = layers.GlobalAveragePooling2D()
+# 利用上一层的输出作为本层的输入,测试其输出
+x = tf.random.normal([4,7,7,2048])
+out = global_average_layer(x) # 池化层降维
+print(out.shape)
+
+
+#%%
+# 新建全连接层
+fc = layers.Dense(100)
+# 利用上一层的输出作为本层的输入,测试其输出
+x = tf.random.normal([4,2048])
+out = fc(x)
+print(out.shape)
+
+
+#%%

+ 36 - 0
ch8/pretained.py

@@ -0,0 +1,36 @@
+#%%
+import  tensorflow as tf
+from    tensorflow import keras
+from    tensorflow.keras import datasets, layers, optimizers, Sequential, metrics
+
+#%%
+# 加载预训练网络模型,并去掉最后一层
+resnet = keras.applications.ResNet50(weights='imagenet',include_top=False)
+resnet.summary()
+# 测试网络的输出
+x = tf.random.normal([4,224,224,3])
+out = resnet(x)
+out.shape
+#%%
+# 新建池化层
+global_average_layer = tf.keras.layers.GlobalAveragePooling2D()
+# 利用上一层的输出作为本层的输入,测试其输出
+x = tf.random.normal([4,7,7,2048])
+out = global_average_layer(x)
+print(out.shape)
+#%%
+# 新建全连接层
+fc = tf.keras.layers.Dense(100)
+# 利用上一层的输出作为本层的输入,测试其输出
+x = tf.random.normal([4,2048])
+out = fc(x)
+print(out.shape)
+#%%
+# 重新包裹成我们的网络模型
+mynet = Sequential([resnet, global_average_layer, fc])
+mynet.summary()
+#%%
+resnet.trainable = False
+mynet.summary()
+
+#%%