第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

全部開發(fā)者教程

TensorFlow 入門教程

首頁 慕課教程 TensorFlow 入門教程 TensorFlow 入門教程 在 TensorFlow 之中自定義網(wǎng)絡(luò)層與模型

在 TensorFlow 之中自定義網(wǎng)絡(luò)層與模型

在上一節(jié)之中,我們學(xué)習(xí)了如何進(jìn)行微分操作以及梯度的求導(dǎo)。那么這節(jié)課我們便開始自定義的下一步 —— 自定義網(wǎng)絡(luò)層與模型。

這節(jié)課主要分為兩個(gè)大部分進(jìn)行講解,它們分別是:

  • 自定義網(wǎng)絡(luò)層;
  • 自定義模型。

我們會(huì)分別對(duì)這兩個(gè)方面進(jìn)行講解。而網(wǎng)絡(luò)層是模型的基礎(chǔ),因此我們會(huì)對(duì)網(wǎng)絡(luò)層進(jìn)行著重的講解。

1. 如何自定義網(wǎng)絡(luò)層

在 TensorFlow 之中,我們目前一般采用創(chuàng)建 keras 層的方式來進(jìn)行網(wǎng)絡(luò)層的構(gòu)建,因此,我們的創(chuàng)建步驟大致分為以下幾步:

  • 定義網(wǎng)絡(luò)層的類并繼承 tf.keras.layers.Layer 類;
  • 在初始化方法或者 build 方法之中定義網(wǎng)絡(luò)的參數(shù);
  • 在 call 函數(shù)之中編寫具體的處理流程。

在第二步之中,我們可以在初始化或者 build 方法之中定義網(wǎng)絡(luò)的參數(shù),兩者的效果在目前的教程之中時(shí)一樣的,因此為了簡單起見,我們統(tǒng)一在初始化函數(shù)之中定義我們的網(wǎng)絡(luò)參數(shù)。

以下是一個(gè)簡單的例子:

import tensorflow as tf

class MyLayer(tf.keras.layers.Layer):
    def __init__(self, hidden_units, input_units):
        super(MyLayer, self).__init__()
        self.w = self.add_weight(shape=(input_units, hidden_units), initializer="random_normal")
        self.b = self.add_weight(shape=(hidden_units,), initializer="random_normal")

    def call(self, inputs):
        return tf.matmul(tf.matmul(inputs, inputs), self.w) + self.b

在這個(gè)例子之中,我們定義了一個(gè)網(wǎng)絡(luò)層,該網(wǎng)絡(luò)層的數(shù)學(xué)形式為:

y = w*(x**2) + b

我們讓 x 進(jìn)行平方之后乘上一個(gè)系數(shù) w ,然后加上一個(gè)常數(shù)項(xiàng) b 。

通過代碼我們可以發(fā)現(xiàn),我們?cè)诔跏蓟瘮?shù)之中進(jìn)行了參數(shù)的初始化操作,然后再在 call 方式之中進(jìn)行了具體的計(jì)算。

對(duì)于添加參數(shù),我們最常用的方式是采用 add_weight 方法來進(jìn)行的;該方法最常用的參數(shù)有兩個(gè):

  • shape: 表示該參數(shù)的形狀,比如 3x3 等;
  • initializer: 初始化器,一般為 “zeros”(初始化為 0),或者 “random_normal”(隨機(jī)初始化)。

我們可以通過具體的數(shù)據(jù)進(jìn)行查看:

x = tf.ones((5, 5))
my_layer = MyLayer(10, 5)
y = my_layer(x)
print(y)

輸出為:

tf.Tensor(
[[ 0.5975663   0.46636996 -0.4837241   0.3024946   0.33699942  0.1420103
   0.07284987 -0.5888218   0.13172552  0.01993698]
 [ 0.5975663   0.46636996 -0.4837241   0.3024946   0.33699942  0.1420103
   0.07284987 -0.5888218   0.13172552  0.01993698]
 [ 0.5975663   0.46636996 -0.4837241   0.3024946   0.33699942  0.1420103
   0.07284987 -0.5888218   0.13172552  0.01993698]
 [ 0.5975663   0.46636996 -0.4837241   0.3024946   0.33699942  0.1420103
   0.07284987 -0.5888218   0.13172552  0.01993698]
 [ 0.5975663   0.46636996 -0.4837241   0.3024946   0.33699942  0.1420103
   0.07284987 -0.5888218   0.13172552  0.01993698]], shape=(5, 10), dtype=float32)

因此我們可以發(fā)現(xiàn)我們的網(wǎng)絡(luò)成功的得到了輸出。但是因?yàn)槲覀兪请S機(jī)初始化的參數(shù),因此輸出一定會(huì)是雜亂無章的。

2. 網(wǎng)絡(luò)層中的固定參數(shù)

在上面的例子中,我們學(xué)習(xí)到了如何對(duì)自己的網(wǎng)絡(luò)層添加參數(shù),但是我們會(huì)發(fā)現(xiàn),我們剛剛添加的參數(shù)都是可以進(jìn)行訓(xùn)練的參數(shù),那么如何添加不可訓(xùn)練的參數(shù)呢?

我們可以在添加參數(shù)的方法之中添加屬性 trainable

self.b = self.add_weight(shape=(hidden_units,), initializer="random_normal", trainable=False)

通過 trainable 屬性,我們可以將該參數(shù)設(shè)置為不可訓(xùn)練的參數(shù),也就是說,在以后的訓(xùn)練過程之中,該參數(shù)不會(huì)改變,而是一直保持不變的狀態(tài)。

我們可以通過以下代碼進(jìn)行實(shí)踐:

class MyLayer2(tf.keras.layers.Layer):
    def __init__(self, hidden_units, input_units):
        super(MyLayer2, self).__init__()
        self.w = self.add_weight(shape=(input_units, hidden_units), initializer="random_normal")
        self.b = self.add_weight(shape=(hidden_units,), initializer="random_normal", trainable=False)

    def call(self, inputs):
        return tf.matmul(tf.matmul(inputs, inputs), self.w) + self.b

my_layer2 = MyLayer2(10, 5)
print(len(my_layer.trainable_weights))
print(len(my_layer2.trainable_weights))

輸出為:

2
1

在該程序之中,我們定義了兩個(gè)模型,一個(gè)模型的 b 可訓(xùn)練,另一個(gè)模型的 b 不可訓(xùn)練,于是我們可以發(fā)現(xiàn),兩個(gè)模型的可訓(xùn)練參數(shù)不一樣,說明我們的屬性起到了相應(yīng)的效果。

3. 決定網(wǎng)絡(luò)是否進(jìn)行訓(xùn)練

我們的網(wǎng)絡(luò)在使用的時(shí)候包括兩個(gè)情景:

  • 訓(xùn)練的情景,需要我們進(jìn)行參數(shù)的調(diào)整等;
  • 測(cè)試的情景或其他情景,固定參數(shù),只進(jìn)行輸出。

在大多數(shù)時(shí)間,我們都需要在訓(xùn)練或者測(cè)試的過程之中做一些額外的操作。

而我們的網(wǎng)絡(luò)是默認(rèn)進(jìn)行訓(xùn)練的,那么如何才能將我們的網(wǎng)絡(luò)調(diào)整為測(cè)試狀態(tài)或是訓(xùn)練狀態(tài)呢?答案就是 call 方法的參數(shù):training。

如以下示例:

class MyLayer2(tf.keras.layers.Layer):
    def __init__(self, hidden_units, input_units):
        super(MyLayer2, self).__init__()
        self.w = self.add_weight(shape=(input_units, hidden_units), initializer="random_normal")
        self.b = self.add_weight(shape=(hidden_units,), initializer="random_normal", trainable=False)

    def call(self, inputs, training=True):
        if training:
          self.b = self.b * 2
          # ...... Other Operations
        return tf.matmul(tf.matmul(inputs, inputs), self.w) + self.b

我們?cè)?call 之中定義了 training 參數(shù),從而可以根據(jù)是否進(jìn)行訓(xùn)練進(jìn)行額外的操作,我們可以通過如下方式來具體使用:

my_layer2 = MyLayer2(10, 5)
y = my_layer2(x, traing=True)
y = my_layer2(x, traing=False)

于是我們?cè)诘谝徽{(diào)用的時(shí)候進(jìn)行訓(xùn)練,而第二次調(diào)用的時(shí)候不進(jìn)行訓(xùn)練。

4. 網(wǎng)絡(luò)層的嵌套使用

在網(wǎng)絡(luò)層的使用之中,我們可能會(huì)遇到網(wǎng)絡(luò)層嵌套使用的情況。而且 TensorFlow 也可以支持網(wǎng)絡(luò)層的嵌套使用。

比如以下代碼:

class MyLayer(tf.keras.layers.Layer):
    def __init__(self, hidden_units, input_units):
        super(MyLayer, self).__init__()
        self.w = self.add_weight(shape=(input_units, hidden_units), initializer="random_normal")
        self.b = self.add_weight(shape=(hidden_units,), initializer="random_normal")

    def call(self, inputs):
        return tf.matmul(tf.matmul(inputs, inputs), self.w) + self.b

class MyLayer2(tf.keras.layers.Layer):
    def __init__(self, hidden_units, input_units):
        super(MyLayer2, self).__init__()
        self.w = self.add_weight(shape=(input_units, hidden_units), initializer="random_normal")
        self.b = self.add_weight(shape=(hidden_units,), initializer="random_normal", trainable=False)

    def call(self, inputs, training=True):
        return tf.matmul(inputs, self.w) + self.b

class MyLayer3(tf.keras.layers.Layer):
    def __init__(self):
        super(MyLayer3, self).__init__()
        self.l1 = MyLayer(10, 5)
        self.l2 = MyLayer2(5, 10)

    def call(self, inputs, training=True):
        x = self.l1(inputs)
        y = self.l2(x)
        return y

在這個(gè)網(wǎng)絡(luò)層之中,我們?cè)谇懊嬷匦露x了兩個(gè)網(wǎng)絡(luò)層類,并在后面我們嵌套了我們之前的兩個(gè)網(wǎng)絡(luò)層,我們通過順序調(diào)用來實(shí)現(xiàn)了一個(gè)新的網(wǎng)絡(luò)層的操作。

我們可以通過具體的數(shù)據(jù)進(jìn)行測(cè)試:

x = tf.ones((5, 5))
my_layer = MyLayer3(10, 5)
y = my_layer(x)
print(y)

我們可以得到輸出:

tf.Tensor(
[[ 0.00422265  0.02767846  0.04585129  0.10204907 -0.08051172]
 [ 0.00422265  0.02767846  0.04585129  0.10204907 -0.08051172]
 [ 0.00422265  0.02767846  0.04585129  0.10204907 -0.08051172]
 [ 0.00422265  0.02767846  0.04585129  0.10204907 -0.08051172]
 [ 0.00422265  0.02767846  0.04585129  0.10204907 -0.08051172]], shape=(5, 5), dtype=float32)

可以發(fā)現(xiàn),我們的程序成功地運(yùn)行了相應(yīng)的數(shù)據(jù),并產(chǎn)生了結(jié)果。

5. 自定義模型

既然了解了如何自定義網(wǎng)絡(luò)層,那么便要知道如何自定義網(wǎng)絡(luò)模型,其實(shí)網(wǎng)絡(luò)模型是由網(wǎng)絡(luò)層構(gòu)成的,因此只要將網(wǎng)絡(luò)層定義清楚,那么網(wǎng)絡(luò)模型便可以很輕松得到了。

網(wǎng)絡(luò)模型的構(gòu)建大致也分為以下幾步:

  • 自定義模型類,并繼承自 tf.keras.Model 類;
  • 初始化函數(shù)之中定義要用到的網(wǎng)絡(luò)層;
  • 在 call 函數(shù)之中定義具體的處理方式

于是,借用上面的網(wǎng)絡(luò)層,我們可以定義我們的網(wǎng)絡(luò)模型:


class MyModel(tf.keras.Model):
    def __init__(self):
        super(MyModel, self).__init__()
        self.l1 = MyLayer(10, 5)
        self.l2 = MyLayer2(5, 10)

    def call(self, inputs, training=True):
        x = self.l1(inputs)
        y = self.l2(x)
        return y

我們的網(wǎng)絡(luò)模型使用了 MyLayer 和 MyLayer2 兩個(gè)網(wǎng)絡(luò)層,并且在 call 函數(shù)之中進(jìn)行了順序處理,從而得到最后的結(jié)果。

我們可以通過測(cè)試:

x = tf.ones((5, 5))
model = MyModel()
y = model(x)
print(y)

得到輸出:

tf.Tensor(
[[ 0.07020754 -0.14177878 -0.00841531 -0.0398875   0.14821295]
 [ 0.07020754 -0.14177878 -0.00841531 -0.0398875   0.14821295]
 [ 0.07020754 -0.14177878 -0.00841531 -0.0398875   0.14821295]
 [ 0.07020754 -0.14177878 -0.00841531 -0.0398875   0.14821295]
 [ 0.07020754 -0.14177878 -0.00841531 -0.0398875   0.14821295]], shape=(5, 5), dtype=float32)

我們發(fā)現(xiàn)我們的網(wǎng)絡(luò)模型也是很正確的進(jìn)行了輸出。

6. 小結(jié)

在這節(jié)課之中,我們學(xué)習(xí)了如何自定義網(wǎng)絡(luò)層,如何指定網(wǎng)絡(luò)層參數(shù)是否訓(xùn)練,如何進(jìn)行運(yùn)行模式的指定以及如何進(jìn)行網(wǎng)絡(luò)層嵌套等,最后我們又學(xué)習(xí)了如何進(jìn)行自定義網(wǎng)絡(luò)的構(gòu)建。