Тренируйте только смещение в предварительно обученной модели из Keras-Tensorflow

#python #tensorflow #keras #bias-neuron

#python #tensorflow #keras #смещение-нейрон

Вопрос:

Звучит странно, я знаю! но: возможно ли обучить только смещению? У меня есть предварительно обученные модели, но, применяя низкий ранг к весам, очевидно, точность NN снижается… Можно ли вообще сказать, что компилятор Keras-TensoFlow обучает только смещению? Конечно, я не знаю, действительно ли это имеет смысл (я полагаю, что это глупая идея …), Но я хочу проверить, увеличивается ли точность или нет..

Ответ №1:

Вы можете вручную выбрать переменные для обновления при применении градиентов следующим образом:

 def get_grad(model, x, y):
    with tf.GradientTape() as tape:
        loss = compute_loss(model, x, y, training=True)
        to_update = [i for ix, i in enumerate(model.trainable_variables) if ix in (1, 3, 5, 7)]
    return loss, tape.gradient(loss, to_update)
 

Он возвращает переменные 1, 3, 5, 7, которые являются смещениями. И да, это работает:

 Epoch 10 Loss: 1.013 Acc: 33.33%
Epoch 11 Loss: 1.006 Acc: 34.00%
Epoch 12 Loss: 0.999 Acc: 34.00%
Epoch 13 Loss: 0.993 Acc: 36.00%
Epoch 14 Loss: 0.987 Acc: 39.33%
Epoch 15 Loss: 0.982 Acc: 48.67%
Epoch 16 Loss: 0.979 Acc: 53.33%
Epoch 17 Loss: 0.975 Acc: 56.00%
Epoch 18 Loss: 0.972 Acc: 59.33%
Epoch 19 Loss: 0.969 Acc: 60.67%
Epoch 20 Loss: 0.967 Acc: 61.33%
Epoch 21 Loss: 0.966 Acc: 61.33%
Epoch 22 Loss: 0.962 Acc: 61.33%
Epoch 23 Loss: 0.961 Acc: 62.67%
Epoch 24 Loss: 0.961 Acc: 62.00%
Epoch 25 Loss: 0.959 Acc: 62.67%
 

Полный код:

 import tensorflow as tf
from tensorflow.keras.layers import Dense
from sklearn.datasets import load_iris
import numpy as np

X, y = load_iris(return_X_y=True)
X = X.astype(np.float32)

train = tf.data.Dataset.from_tensor_slices((X, y)).shuffle(25).batch(8)

model = tf.keras.Sequential([
    Dense(16, activation='relu'),
    Dense(32, activation='relu'),
    Dense(64, activation='relu'),
    Dense(3, activation='softmax')])

loss_object = tf.losses.SparseCategoricalCrossentropy(from_logits=False)


def compute_loss(model, x, y, training):
  out = model(x, training=training)
  loss = loss_object(y_true=y, y_pred=out)
  return loss


def get_grad(model, x, y):
    with tf.GradientTape() as tape:
        loss = compute_loss(model, x, y, training=True)
        to_update = [i for ix, i in enumerate(model.trainable_variables) if ix in (1, 3, 5, 7)]
    return loss, tape.gradient(loss, to_update)


optimizer = tf.optimizers.Adam()

verbose = "Epoch {:2d} Loss: {:.3f} Acc: {:.2%}"

model.build(input_shape=([None, 4]))
weights_before = model.layers[0].get_weights()

for epoch in range(1, 25   1):
    train_loss = tf.metrics.Mean()
    train_acc = tf.metrics.SparseCategoricalAccuracy()

    for x, y in train:
        loss_value, grads = get_grad(model, x, y)
        to_update = [i for ix, i in enumerate(model.trainable_variables) if ix in (1, 3, 5, 7)]
        optimizer.apply_gradients(zip(grads, to_update))
        train_loss.update_state(loss_value)
        train_acc.update_state(y, model(x, training=True))

    print(verbose.format(epoch,
                         train_loss.result(),
                         train_acc.result()))

weights_after = model.layers[0].get_weights()