<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          淺談keras的擴(kuò)展性:自定義keras

          共 6728字,需瀏覽 14分鐘

           ·

          2020-10-20 18:50


          1. 自定義keras

          keras是一種深度學(xué)習(xí)的API,能夠快速實現(xiàn)你的實驗。keras也集成了很多預(yù)訓(xùn)練的模型,可以實現(xiàn)很多常規(guī)的任務(wù),如圖像分類。TensorFlow 2.0之后tensorflow本身也變的很keras化。

          另一方面,keras表現(xiàn)出高度的模塊化和封裝性,所以有的人會覺得keras不易于擴(kuò)展, 比如實現(xiàn)一種新的Loss,新的網(wǎng)絡(luò)層結(jié)構(gòu);其實可以通過keras的基礎(chǔ)模塊進(jìn)行快速的擴(kuò)展,實現(xiàn)更新的算法。

          本文就keras的擴(kuò)展性,總結(jié)了對layer,model和loss的自定義。

          2. 自定義keras layers

          layers是keras中重要的組成部分,網(wǎng)絡(luò)結(jié)構(gòu)中每一個組成都要以layers來表現(xiàn)。keras提供了很多常規(guī)的layer,如Convolution layers,pooling layers, activation layers, dense layers等, 我們可以通過繼承基礎(chǔ)layers來擴(kuò)展自定義的layers。

          2.1 base layer

          layer實了輸入tensor和輸出tensor的操作類,以下為base layer的5個方法,自定義layer只要重寫這些方法就可以了。

          • init(): 定義自定義layer的一些屬性
          • build(self, input_shape):定義layer需要的權(quán)重weights
          • call(self, *args, **kwargs):layer具體的操作,會在調(diào)用自定義layer自動執(zhí)行
          • get_config(self):layer初始化的配置,是一個字典dictionary。
          • compute_output_shape(self,input_shape):計算輸出tensor的shape

          2.2 例子

          #?標(biāo)準(zhǔn)化層
          class?InstanceNormalize(Layer):
          ????def?__init__(self,?**kwargs):
          ????????super(InstanceNormalize,?self).__init__(**kwargs)
          ????????self.epsilon?=?1e-3
          ????????????

          ????def?call(self,?x,?mask=None):
          ????????mean,?var?=?tf.nn.moments(x,?[1,?2],?keep_dims=True)
          ????????return?tf.div(tf.subtract(x,?mean),?tf.sqrt(tf.add(var,?self.epsilon)))

          ?????????????????????????????????????????????????
          ????def?compute_output_shape(self,input_shape):
          ????????return?input_shape

          #?調(diào)用
          inputs?=?keras.Input(shape=(None,?None,?3))
          x?=?InstanceNormalize()(inputs)
          #?可以通過add_weight()?創(chuàng)建權(quán)重
          class?SimpleDense(Layer):

          ??def?__init__(self,?units=32):
          ??????super(SimpleDense,?self).__init__()
          ??????self.units?=?units

          ??def?build(self,?input_shape):
          ??????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

          #?調(diào)用
          inputs?=?keras.Input(shape=(None,?None,?3))
          x?=?SimpleDense(units=64)(inputs)

          3. 自定義keras model

          我們在定義完網(wǎng)絡(luò)結(jié)構(gòu)時,會把整個工作流放在keras.Model, 進(jìn)行compile(), 然后通過fit()進(jìn)行訓(xùn)練過程。執(zhí)行fit()的時候,執(zhí)行每個batch size data的時候,都會調(diào)用Modeltrain_step(self, data)

          from?keras.models?import?Sequential
          from?keras.layers?import?Dense,?Activation
          model?=?Sequential()

          model.add(Dense(units=64,?input_dim=100))
          model.add(Activation("relu"))
          model.add(Dense(units=10))
          model.add(Activation("softmax"))

          model.compile(loss='categorical_crossentropy',?optimizer='sgd',?metrics=['accuracy'])

          model.fit(x_train,?y_train,?epochs=5,?batch_size=32)

          當(dāng)你需要自己控制訓(xùn)練過程的時候,可以重寫Modeltrain_step(self, data)方法

          class?CustomModel(keras.Model):
          ????def?train_step(self,?data):
          ????????#?Unpack?the?data.?Its?structure?depends?on?your?model?and
          ????????#?on?what?you?pass?to?`fit()`.
          ????????x,?y?=?data

          ????????with?tf.GradientTape()?as?tape:
          ????????????y_pred?=?self(x,?training=True)??#?Forward?pass
          ????????????#?Compute?the?loss?value
          ????????????#?(the?loss?function?is?configured?in?`compile()`)
          ????????????loss?=?self.compiled_loss(y,?y_pred,?regularization_losses=self.losses)

          ????????#?Compute?gradients
          ????????trainable_vars?=?self.trainable_variables
          ????????gradients?=?tape.gradient(loss,?trainable_vars)
          ????????#?Update?weights
          ????????self.optimizer.apply_gradients(zip(gradients,?trainable_vars))
          ????????#?Update?metrics?(includes?the?metric?that?tracks?the?loss)
          ????????self.compiled_metrics.update_state(y,?y_pred)
          ????????#?Return?a?dict?mapping?metric?names?to?current?value
          ????????return?{m.name:?m.result()?for?m?in?self.metrics}

          import?numpy?as?np

          #?Construct?and?compile?an?instance?of?CustomModel
          inputs?=?keras.Input(shape=(32,))
          outputs?=?keras.layers.Dense(1)(inputs)
          model?=?CustomModel(inputs,?outputs)
          model.compile(optimizer="adam",?loss="mse",?metrics=["mae"])

          #?Just?use?`fit`?as?usual
          x?=?np.random.random((1000,?32))
          y?=?np.random.random((1000,?1))
          model.fit(x,?y,?epochs=3)

          4. 自定義keras loss

          keras實現(xiàn)了交叉熵等常見的loss,自定義loss對于使用keras來說是比較常見,實現(xiàn)各種魔改loss,如focal loss。

          我們來看看keras源碼中對loss實現(xiàn)

          def?categorical_crossentropy(y_true,?y_pred):
          ????return?K.categorical_crossentropy(y_true,?y_pred)

          def?mean_squared_error(y_true,?y_pred):
          ????return?K.mean(K.square(y_pred?-?y_true),?axis=-1)

          可以看出輸入是groud true y_true和預(yù)測值y_pred, 返回為計算loss的函數(shù)。自定義loss可以參照如此模式即可。

          def?focal_loss(weights=None,?alpha=0.25,?gamma=2):
          ????r"""Compute?focal?loss?for?predictions.
          ????????Multi-labels?Focal?loss?formula:
          ????????????FL?=?-alpha?*?(z-p)^gamma?*?log(p)?-(1-alpha)?*?p^gamma?*?log(1-p)
          ?????????????????,which?alpha?=?0.25,?gamma?=?2,?p?=?sigmoid(x),?z?=?target_tensor.
          ????#?https://github.com/ailias/Focal-Loss-implement-on-Tensorflow/blob/master/focal_loss.py
          ????Args:
          ?????prediction_tensor:?A?float?tensor?of?shape?[batch_size,?num_anchors,
          ????????num_classes]?representing?the?predicted?logits?for?each?class
          ?????target_tensor:?A?float?tensor?of?shape?[batch_size,?num_anchors,
          ????????num_classes]?representing?one-hot?encoded?classification?targets
          ?????weights:?A?float?tensor?of?shape?[batch_size,?num_anchors]
          ?????alpha:?A?scalar?tensor?for?focal?loss?alpha?hyper-parameter
          ?????gamma:?A?scalar?tensor?for?focal?loss?gamma?hyper-parameter
          ????Returns:
          ????????loss:?A?(scalar)?tensor?representing?the?value?of?the?loss?function
          ????"""


          ????def?_custom_loss(y_true,?y_pred):
          ????????sigmoid_p?=?tf.nn.sigmoid(y_pred)
          ????????zeros?=?array_ops.zeros_like(sigmoid_p,?dtype=sigmoid_p.dtype)

          ????????#?For?poitive?prediction,?only?need?consider?front?part?loss,?back?part?is?0;
          ????????#?target_tensor?>?zeros?<=>?z=1,?so?poitive?coefficient?=?z?-?p.
          ????????pos_p_sub?=?array_ops.where(y_true?>?zeros,?y_true?-?sigmoid_p,?zeros)

          ????????#?For?negative?prediction,?only?need?consider?back?part?loss,?front?part?is?0;
          ????????#?target_tensor?>?zeros?<=>?z=1,?so?negative?coefficient?=?0.
          ????????neg_p_sub?=?array_ops.where(y_true?>?zeros,?zeros,?sigmoid_p)
          ????????per_entry_cross_ent?=?-?alpha?*?(pos_p_sub?**?gamma)?*?tf.log(tf.clip_by_value(sigmoid_p,?1e-8,?1.0))?\
          ??????????????????????????????-?(1?-?alpha)?*?(neg_p_sub?**?gamma)?*?tf.log(
          ????????????tf.clip_by_value(1.0?-?sigmoid_p,?1e-8,?1.0))
          ????????return?tf.reduce_sum(per_entry_cross_ent)

          ????return?_custom_loss

          5. 總結(jié)

          本文分享了keras的擴(kuò)展功能,擴(kuò)展功能其實也是實現(xiàn)Keras模塊化的一種繼承實現(xiàn)。

          總結(jié)如下:

          • 繼承Layer實現(xiàn)自定義layer, 記住bulid() call()
          • 繼續(xù)Model實現(xiàn)train_step定義訓(xùn)練過程,記住梯度計算tape.gradient(loss, trainable_vars) ,權(quán)重更新optimizer.apply_gradients, 計算evaluate compiled_metrics.update_state(y, y_pred)
          • 魔改loss,記住groud true y_true和預(yù)測值y_pred輸入,返回loss function

          作者簡介:wedo實驗君, 數(shù)據(jù)分析師;熱愛生活,熱愛寫作


          贊 賞 作 者


          Python中文社區(qū)作為一個去中心化的全球技術(shù)社區(qū),以成為全球20萬Python中文開發(fā)者的精神部落為愿景,目前覆蓋各大主流媒體和協(xié)作平臺,與阿里、騰訊、百度、微軟、亞馬遜、開源中國、CSDN等業(yè)界知名公司和技術(shù)社區(qū)建立了廣泛的聯(lián)系,擁有來自十多個國家和地區(qū)數(shù)萬名登記會員,會員來自以工信部、清華大學(xué)、北京大學(xué)、北京郵電大學(xué)、中國人民銀行、中科院、中金、華為、BAT、谷歌、微軟等為代表的政府機(jī)關(guān)、科研單位、金融機(jī)構(gòu)以及海內(nèi)外知名公司,全平臺近20萬開發(fā)者關(guān)注。

          長按掃碼添加“Python小助手”



          ▼點(diǎn)擊成為社區(qū)會員? ?喜歡就點(diǎn)個在看吧

          瀏覽 68
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  色综合高清在线观看视频 | 奇米成人网站 | 香蕉视频视频禁止十八 | 精品一区二区三区四 | 婷婷久久福利 |