keras打印loss对权重的导数方式

作者:HackerTom 时间:2023-05-17 18:21:11 

Notes

怀疑模型梯度 * ,想打印模型 loss 对各权重的导数看看。如果如果fit来训练的话,可以用keras.callbacks.TensorBoard实现。

但此次使用train_on_batch来训练的,用K.gradients和K.function实现。

Codes

以一份 VAE 代码为例


# -*- coding: utf8 -*-
import keras
from keras.models import Model
from keras.layers import Input, Lambda, Conv2D, MaxPooling2D, Flatten, Dense, Reshape
from keras.losses import binary_crossentropy
from keras.datasets import mnist, fashion_mnist
import keras.backend as K
from scipy.stats import norm
import numpy as np
import matplotlib.pyplot as plt

BATCH = 128
N_CLASS = 10
EPOCH = 5
IN_DIM = 28 * 28
H_DIM = 128
Z_DIM = 2

(x_train, y_train), (x_test, y_test) = fashion_mnist.load_data()
x_train = x_train.reshape(len(x_train), -1).astype('float32') / 255.
x_test = x_test.reshape(len(x_test), -1).astype('float32') / 255.

def sampleing(args):
 """reparameterize"""
 mu, logvar = args
 eps = K.random_normal([K.shape(mu)[0], Z_DIM], mean=0.0, stddev=1.0)
 return mu + eps * K.exp(logvar / 2.)

# encode
x_in = Input([IN_DIM])
h = Dense(H_DIM, activation='relu')(x_in)
z_mu = Dense(Z_DIM)(h) # mean,不用激活
z_logvar = Dense(Z_DIM)(h) # log variance,不用激活
z = Lambda(sampleing, output_shape=[Z_DIM])([z_mu, z_logvar]) # 只能有一个参数
encoder = Model(x_in, [z_mu, z_logvar, z], name='encoder')

# decode
z_in = Input([Z_DIM])
h_hat = Dense(H_DIM, activation='relu')(z_in)
x_hat = Dense(IN_DIM, activation='sigmoid')(h_hat)
decoder = Model(z_in, x_hat, name='decoder')

# VAE
x_in = Input([IN_DIM])
x = x_in
z_mu, z_logvar, z = encoder(x)
x = decoder(z)
out = x
vae = Model(x_in, [out, out], name='vae')

# loss_kl = 0.5 * K.sum(K.square(z_mu) + K.exp(z_logvar) - 1. - z_logvar, axis=1)
# loss_recon = binary_crossentropy(K.reshape(vae_in, [-1, IN_DIM]), vae_out) * IN_DIM
# loss_vae = K.mean(loss_kl + loss_recon)

def loss_kl(y_true, y_pred):
 return 0.5 * K.sum(K.square(z_mu) + K.exp(z_logvar) - 1. - z_logvar, axis=1)

# vae.add_loss(loss_vae)
vae.compile(optimizer='rmsprop',
     loss=[loss_kl, 'binary_crossentropy'],
     loss_weights=[1, IN_DIM])
vae.summary()

# 获取模型权重 variable
w = vae.trainable_weights
print(w)

# 打印 KL 对权重的导数
# KL 要是 Tensor,不能是上面的函数 `loss_kl`
grad = K.gradients(0.5 * K.sum(K.square(z_mu) + K.exp(z_logvar) - 1. - z_logvar, axis=1),
         w)
print(grad) # 有些是 None 的
grad = grad[grad is not None] # 去掉 None,不然报错

# 打印梯度的函数
# K.function 的输入和输出必要是 list!就算只有一个
show_grad = K.function([vae.input], [grad])

# vae.fit(x_train, # y_train, # 不能传 y_train
#     batch_size=BATCH,
#     epochs=EPOCH,
#     verbose=1,
#     validation_data=(x_test, None))

''' 以 train_on_batch 方式训练 '''
for epoch in range(EPOCH):
 for b in range(x_train.shape[0] // BATCH):
   idx = np.random.choice(x_train.shape[0], BATCH)
   x = x_train[idx]
   l = vae.train_on_batch([x], [x, x])

# 计算梯度
 gd = show_grad([x])
 # 打印梯度
 print(gd)

# show manifold
PIXEL = 28
N_PICT = 30
grid_x = norm.ppf(np.linspace(0.05, 0.95, N_PICT))
grid_y = grid_x

figure = np.zeros([N_PICT * PIXEL, N_PICT * PIXEL])
for i, xi in enumerate(grid_x):
 for j, yj in enumerate(grid_y):
   noise = np.array([[xi, yj]]) # 必须秩为 2,两层中括号
   x_gen = decoder.predict(noise)
   # print('x_gen shape:', x_gen.shape)
   x_gen = x_gen[0].reshape([PIXEL, PIXEL])
   figure[i * PIXEL: (i+1) * PIXEL,
       j * PIXEL: (j+1) * PIXEL] = x_gen

fig = plt.figure(figsize=(10, 10))
plt.imshow(figure, cmap='Greys_r')
fig.savefig('./variational_autoencoder.png')
plt.show()

补充知识:keras 自定义损失 自动求导时出现None

问题记录,keras 自定义损失 自动求导时出现None,后来想到是因为传入的变量没有使用,所以keras无法求出偏导,修改后问题解决。就是不愿使用的变量×0,求导后还是0就可以了。


def my_complex_loss_graph(y_label, emb_uid, lstm_out,y_true_1,y_true_2,y_true_3,out_1,out_2,out_3):

mse_out_1 = mean_squared_error(y_true_1, out_1)
 mse_out_2 = mean_squared_error(y_true_2, out_2)
 mse_out_3 = mean_squared_error(y_true_3, out_3)
 # emb_uid= K.reshape(emb_uid, [-1, 32])
 cosine_sim = tf.reduce_sum(0.5*tf.square(emb_uid-lstm_out))

cost=0*cosine_sim+K.sum([0.5*mse_out_1 , 0.25*mse_out_2,0.25*mse_out_3],axis=1,keepdims=True)
 # print(mse_out_1)
 final_loss = cost

return K.mean(final_loss)

来源:https://blog.csdn.net/HackerTom/article/details/90177044

标签:keras,loss,权重,导数
0
投稿

猜你喜欢

  • Python真题案例之二分法查找详解

    2023-09-23 01:39:07
  • 使用Golang的singleflight防止缓存击穿的方法

    2024-05-22 10:12:29
  • ASP 操作cookies的方法

    2011-03-10 11:24:00
  • vs10安装之后一些列问题

    2024-01-29 11:59:48
  • Python3导入CSV文件的实例(跟Python2有些许的不同)

    2023-09-21 05:19:29
  • Python 读取千万级数据自动写入 MySQL 数据库

    2023-11-08 09:25:47
  • Python中循环后使用list.append()数据被覆盖问题的解决

    2023-02-08 20:45:49
  • python面向对象_详谈类的继承与方法的重载

    2021-03-21 08:38:18
  • python使用matplotlib画饼状图

    2023-04-06 12:23:29
  • vue2.x集成百度UEditor富文本编辑器的方法

    2024-05-28 15:47:59
  • python 使用socket传输图片视频等文件的实现方式

    2022-11-12 11:55:37
  • 正则表达式学习笔记

    2008-04-15 07:44:00
  • 任意定制文本对齐方式:CSS Text Wrapper

    2008-02-03 11:11:00
  • Golang优雅关闭channel的方法示例

    2024-05-03 15:05:44
  • PHP简单实现冒泡排序的方法

    2024-06-07 15:45:49
  • Python语言进阶知识点总结

    2022-11-09 01:21:37
  • Python实现抓取腾讯视频所有电影的示例代码

    2021-09-11 13:17:37
  • python爬虫用mongodb的理由

    2023-09-27 23:06:40
  • 基于numpy中数组元素的切片复制方法

    2023-07-24 03:14:41
  • 自动完成JS类(纯JS, Ajax模式)

    2024-05-11 09:41:59
  • asp之家 网络编程 m.aspxhome.com