GAN的编写 - tensorflow形式(tensorflow与GAN同学习,重点分析训练过程)

2023-11-13

20200901 -
(本文完成于20200902下午,前面内容还算整洁,越到后面因为都是自己思考的过程,就导致文章越来越乱,就算是把自己思考的过程给记录下来吧)

0. 引言

之前的时候对keras框架编写的GAN网络进行了介绍《GAN的学习 - 训练过程(冻结判别器)》,但是发现去查看源代码的时候,经常有使用tensorflow框架编写的代码,所以寻思着把tensorflow框架也学一学,但是发现很多内容与keras是不一样的,例如可以自己定位网络参数,训练过程也不仅仅是fit那么简单;在涉及GAN时,更不需要利用trainable这种属性来实现判别器的冻结。
本篇文章学习一下利用tensorflow来进行GAN的编写,一方面是学习tensorflow的代码形式,一方面是学习GAN。

总结(20200910增加)

这里总结一下经过我这么多天潜移默化的理解,最近这些天一直都是在看WGAN及WGAN-GP的内容,同时因为是直接利用tensorflow,这种接近底层数学公式的方式来编程,所以对整体的内容是相对理解更深入了。

  1. 在判别器的优化过程中,就是使用普通的交叉熵函数作为损失函数来进行优化,不管是论文中的伪代码还是实际中的代码都没有什么难度
  2. 在生成器的优化过程中,要考虑一个对抗的过程,也就是往着判别器的反方向来进行优化,这也是实际的论文中伪代码所阐述的内容(注意,按照我的理解,论文中的伪代码应该是使用了0作为标签来训练生成器),没有什么问题;主要的问题是在实际的代码中,使用了tf.log(D_fake)作为损失函数,这一点实际上正是GAN的原作者提出了这种方案。然后理解了这个就能明白,为什么要使用1作为训练生成器的标签了。

1. GAN的代码编写

1.1 原始GAN的简单介绍

关于GAN的具体内容可以查看文章《GAN的学习 - 基础知识了解》。这里要说明的是,在GAN的训练过程中,需要使用两个网络,而且训练过程对两个过程有所区分。而GAN的原始论文训练过程的算法如下:
GAN训练过程
上面的伪代码非常简单,那么下面就来具体说明如何使用tensorflow来进行相应的代码编写。

1.2 tensorflow代码

本部分代码来源于文章[1],生成器和判别器分别使用两层的神经网络来说明,网络结构比较简单,主要是说明代码;而且我觉得,后续自己编写的时候,比如还是写一个GAN,那么就完全可以照着这种模式写,只不过到时要根据进行相应的自己需求的修改。

1.2.1 使用的网络结构

# Discriminator Net
# 两层的判别器模型
X = tf.placeholder(tf.float32, shape=[None, 784], name='X')
D_W1 = tf.Variable(xavier_init([784, 128]), name='D_W1')
D_b1 = tf.Variable(tf.zeros(shape=[128]), name='D_b1')
D_W2 = tf.Variable(xavier_init([128, 1]), name='D_W2')
D_b2 = tf.Variable(tf.zeros(shape=[1]), name='D_b2')
theta_D = [D_W1, D_W2, D_b1, D_b2]

# Generator Net
# 两层的生成器模型
Z = tf.placeholder(tf.float32, shape=[None, 100], name='Z')
G_W1 = tf.Variable(xavier_init([100, 128]), name='G_W1')
G_b1 = tf.Variable(tf.zeros(shape=[128]), name='G_b1')
G_W2 = tf.Variable(xavier_init([128, 784]), name='G_W2')
G_b2 = tf.Variable(tf.zeros(shape=[784]), name='G_b2')
theta_G = [G_W1, G_W2, G_b1, G_b2]

def generator(z):
    G_h1 = tf.nn.relu(tf.matmul(z, G_W1) + G_b1)
    G_log_prob = tf.matmul(G_h1, G_W2) + G_b2
    G_prob = tf.nn.sigmoid(G_log_prob)
    return G_prob

def discriminator(x):
    D_h1 = tf.nn.relu(tf.matmul(x, D_W1) + D_b1)
    D_logit = tf.matmul(D_h1, D_W2) + D_b2
    D_prob = tf.nn.sigmoid(D_logit)
    # 注意这里同时返回了logit
    return D_prob, D_logit

可能还有更简洁的方式来进行编写,但是这里我针对这段代码来进行理解。

  • 定义各层网络的参数
  • 利用函数的方式组织出相应的生成器和判别器

注意,这段代码在网络结构上使用了函数的形式,但我感觉重复使用应该要考虑tensorflow作用域的问题,这里留一个问题后续研究。(虽然看了那么多书介绍tensorflow的书,但是实际应用时,还是有时搞不清楚)。
其与keras的区别:

  • 输入分别是X和Z,而在构造模型时,返回的并不是一个模型(类似keras)而是其输出。
  • 在构造网络时,直接使用各个参数来进行数学运算,而非使用模型的形式
  • 最后的地方,没有模型的编译过程,同时没有直接使用某种类型的损失函数,而是直接对概率进行了输出。
    (20200910 增加)
    从上面的区别中可以看出,tensorflow的形式,就是直接定义了各种运算,从数学的角度来理解更容易。

1.2.2 模型的训练过程

G_sample = generator(Z)
D_real, D_logit_real = discriminator(X)
D_fake, D_logit_fake = discriminator(G_sample)

D_loss = -tf.reduce_mean(tf.log(D_real) + tf.log(1. - D_fake))
G_loss = -tf.reduce_mean(tf.log(D_fake))

# Only update D(X)'s parameters, so var_list = theta_D
D_solver = tf.train.AdamOptimizer().minimize(D_loss, var_list=theta_D)
# Only update G(X)'s parameters, so var_list = theta_G
G_solver = tf.train.AdamOptimizer().minimize(G_loss, var_list=theta_G)

def sample_Z(m, n):
    '''Uniform prior for G(Z)'''
    return np.random.uniform(-1., 1., size=[m, n])

for it in range(1000000):
    X_mb, _ = mnist.train.next_batch(mb_size)
    
    _, D_loss_curr = sess.run([D_solver, D_loss], 
	    feed_dict={X: X_mb, Z: sample_Z(mb_size, Z_dim)})
    _, G_loss_curr = sess.run([G_solver, G_loss], 
    	feed_dict={Z: sample_Z(mb_size, Z_dim)})

从上述代码来看,就是说连损失函数这种东西都需要是自己来控制,上面的的代码中也出现了,而且还要自己控制符号。但是平时使用keras的时候,基本上是不需要考虑这些事情的,所以对这部分内容根本不了解。而这里的关键问题是因为需要对抗学习的过程,一个是最大化,一个是最小化。但是这部分内容,体现在这个实际的权值更新应该是什么地方呢?可以从最开始的是训练算法中也看出,对于两个网络分别采用了最大化最小化的方式。
从这个角度来看,tensorflow的编程方式与keras的编程方式有很大不同。
(前文中的代码,是损失函数自己写的,但在他的github中,更新了这种方式,改为使用了tf的函数)。
(而且,阅读到这里的时候,我就感觉,使用tensorflow的方式更能深入理解神经网络的内容,而keras则是封装的太好了。)

在优化器部分的注释中可以看到,为了控制某一部分网络能够冻结,是在传入变量列表的时候就进行了相应的控制,实现了类似keras的trainable的功能。

2. GAN的训练过程

下午的时候,我一直就是在看这段代码,但是我觉得问题就出在这个训练过程,虽然BP算法什么的都知道,但是映射到代码中的过程不是很熟悉,而且之前的时候也说过,因为使用keras式的编程,对这部分内容一直没有关注,这就导致了根本无法理解这里的损失函数,还有他的梯度下降部分。单纯使用一种神经网络的时候也能理解,既然这样,就从这种方式来进行理解。(问题就出在这里,就是在原始的训练算法部分,要明白他为什么一个是增大,一个是减小。)
再进一步,也就是说GAN的对抗过程,落实到每次训练,应该是怎么样一个梯度修改的过程呢?具体的更新过程
现在算是有点明白了, 重新学习了一下交叉熵损失函数,还有参考了一个博客的说法[2],不过需要注意的是文章[2]中是针对一个完整的损失函数来说的。
完整
下面来从原始论文中,从两个更新过程中分别来说明具体的含义,以及其中的问题。

2.1 针对判别器的训练过程

首先要明白,原始交叉熵的损失函数是带有负号的,这个也是因为我一开始忘了这回事,所以导致一直就想不通他为什么要增加(ascending)权值。
原始交叉熵
上图是原始的交叉熵,其中y是真实的标签值。而对应到实际的GAN的第一个损失函数(也就是第一次采集真实和假数据一起训练的时候),
在这里插入图片描述

他本身就是一个交叉熵的函数。因为假标签的损失部分的数据是生成器产生的。也就是说,原始函数中的两个部分针对每个数据(真假)的时候,只需要看一个就行。判别器在训练过程中,因为后半部分就是假数据的内容,所以没有添加上1-0这个部分。
下面来具体说明一下他的目标。判别器输出是一个概率,也就是经过了sigmod函数计算的。
判别器的目标是尽可能分辨出这些输入的实际标签,也就是真假的结果。同时,如果是对的,就尽可能的把概率调高,而如果判定错误,那么就尽可能将判定缩小。在输入真数据的时候,那么就是logD(x)的部分,如果这个判定错了,概率比较小,那么这部分数值也会大,而如果数值概率就是1,这个数值就会小;在输入假数据的时候,那么正好,本身这个概率就反过来了,你输出一个概率较小,那么本身就是要判定这个类别为假,这个时候1-p正好损失函数也小了。

但是前面也提到了,log函数生成的是负值,要加一个符号,如果是正的,就是应该减小这个东西。这里没有添加负号,所以要增加这个数值。也就是求负值的最大值。
(20200910 增加)
上述部分是比较容易理解的,本质上就是一个简单的交叉熵函数,没有什么难的。对开始这里的困惑,也是因为论文中没有使用负号,而是使用了增加这个梯度的说法,实际上是等价的。不管是伪代码也好,或者实际代码也好,都是没有问题的。

2.2 针对生成器的训练过程

在这里插入图片描述
这里一开始理解的时候也比较疑惑,这里缺少了1-的部分,这正是因为每次训练的时候都是只输入了负例样本,但是,我确实给他了一个正例的标签。但是需要注意的是,这里判别器就已经不动了,他不再改动参数了。但是这里我的确一下子还是没想明白。按说,这个标签已经是真的了,也就是1,应该是前半部分,为什么会是后半部分呢。还是那句话,不管怎么样,交叉熵肯定是必然只剩一个部分,因为1-1的原因,那就是为什么是后半部分。

我昨晚的时候,好好想了一下,还是应该从损失函数入手,也就是从训练这个网络的目的入手,训练这个生成器的目的是什么,应该达到什么样的目标,是最大化这个损失函数,还是最小化这个损失函数,从这个角度就能理解。我中午的时候仔细思考了一下,同时结合这个引用的代码和上面的算法伪代码,他们在处理生成器的时候有些区别,一开始也是这部分理解不了。
在算法伪代码中,训练生成器的时候,还是将标签为0的伪数据输入到整个GAN中,只有这样才能是这个公式。然后,在看他说的,他要减少这个梯度,但是他这里的损失函数是负的,也就是说要最小化这个损失函数。基本上就是上面这些概念了,就能理解了。
再来看GAN的对抗过程,这里训练生成器的时候,判别器是冻结的。在上面训练判别器的时候,他是要最大化这个函数(因为是负的,本质上是最小化负号的),他的目的是为了将判别器的权值能够随着损失函数的最大化来进行变换。而在冻结判别器之后,就是更新生成器的过程是以迷惑判别器为目的,那么怎么来迷惑呢?就是按照最小化这个损失函数,同时权值同步更新。这样就能理解了。


20200910 - 这部分的阐述就是最开始的时候,虽然理解了伪代码中的内容:伪代码在训练生成器的时候,就是将0-负标签输入到生成器中,但是因为这部分和实际引用的代码部分(见下文)产生了冲突,所以一时理解不了。其实经过了这几天我的文章阅读,在很多文章中都指出,GAN的论文作者已经指出,可以使用代码中的形式来做为损失函数,但是这种损失函数当然是使用1作为标签。

(20200910 - 增加)
本质上,问题在于伪代码是log(1 - D_fake),而实际代码是log(D_fake),在最开始记录这部分内容的时候就是因为不理解这个问题。而实际上,在文章[1]和[3]中都说明了这部分内容其实是原始GAN论文作者说明的,可以使用log(D_fake)来替换前面的。不过,但是我没看到,而且没有看原始的GAN论文,所以一直就纠结这部分内容,但最后也是凭逻辑上的推理来结局的,并没有找到实际的数学上的证明。不过,也算是有了一部分理解。
GAN原文的作者的建议:在训练过程中,可以将最小化log(1 - D_fake)变为最大化log(D_fake)
(20200910 - 增加结束)

下面的部分是针对代码中的内容进行理解,与前文的伪代码没有关系

G_sample = generator(Z)
D_real, D_logit_real = discriminator(X)
D_fake, D_logit_fake = discriminator(G_sample)

D_loss = -tf.reduce_mean(tf.log(D_real) + tf.log(1. - D_fake))
G_loss = -tf.reduce_mean(tf.log(D_fake))

# Only update D(X)'s parameters, so var_list = theta_D
D_solver = tf.train.AdamOptimizer().minimize(D_loss, var_list=theta_D)
# Only update G(X)'s parameters, so var_list = theta_G
G_solver = tf.train.AdamOptimizer().minimize(G_loss, var_list=theta_G)

(即使是重新阅读这部分内容,还是花费了我很多时间来理解,感觉还是没有吃透这个损失函数的内容)

而在实际代码中,见上。(在文章[1]中也提到,tensorflow支持的是最小化梯度下降,这个可能也是一个原因把),(这部分在原来使用keras的时候也是,将生成数据的标签按照真来输入)。如果按照标签真的输入,那么损失函数应该就是交叉熵的前半部分,判别器就要降低这部分的损失函数,那么为了是新对抗过程,生成器应该增大这部分损失函数,但是这里也说不通。

如果仅仅是从代码的角度来讲,那么他最小化这个-tf.reduce_mean(tf.log(D_fake)),本质上就是最大化-tf.reduce_mean(tf.log(1-D_fake))。这样从数学的角度来理解好像是对的,因为前面判别器的权值就是要朝着最小化的方向来更新,这样就对应了那个过程。但是还是那句话,这种方式没有从实际意义上来理解,就是为什么把他当作是真的之后,没有这么一个过程。
所以我这里疑惑的问题是,如果是将损失函数变为了-tf.log(D_fake)形式,那么应该怎么从实际的意义上来理解。看对抗的过程,假设这部分输入的是真数据,那么判别器要降低这部分数值,而生成器应该是增大这部分数值。但实际上,这部分是假数据,判别器就会发现这里面很多内容都不对,那么肯定是自己的参数有问题,然后有了损失函数,但在该过程中,判别器实际上是被冻结的,所以这部分的损失函数就传到到了前面。使用正标签的意义就在于,本身判别器就能区分出来,那么就不需要对抗的过程,此时的损失函数也比较小。生成器,就是要最小化这个损失函数,这个损失函数是以欺骗判别器为代价,让他以为这个是正数据,而当我的生成器真的能够输出一个类似真的数据的时候,那么此时的这个损失函数也是最小的。

而如果是仅仅从为了训练的角度出发,也就是从损失函数的角度出发,本来是使用log(1-D_fake)的,但是现在换成了log(D_fake)。从生成器的角度来说,因为传递给判别器的数据是假的,那么此时的损失函数是很大的,所以能够利用这部分的梯度传递回来,最后根据这部分梯度来判定进行权值更新,最终就是能够让判别器能够输出一个比较小的损失函数,也就是说此时判别器已经可以认为这部分数据很像是真的了。本质上,最小化生成器生成的假数据(例如,图片)在判别器的部分也能够得到很小的损失函数。但是这个东西怎么跟对抗挂钩呢?就是判别器是怎么形成了一个反向的更新过程呢?那么从判别器的角度出发,如果它知道这个东西是假的,也就是传递进去的标签是假的,那么它必然是最小化这个数值,-log(1 - D_fake)。但是我传递进去假的,如果这部分梯度被判别器所吸收,然后进行相应的更新,必然是往反方向更新了,其实就是底层的标签被调换了,在概率上他以真数据为主。所以从这个角度是一个对抗过程。

而替换伪log(D_fake)的原因,我觉得是梯度的问题,或者说是损失函数大小的问题。原始的论文损失函数为log(1 - D_fake),而生成器的目的与判别器想法,是为了最大化的这个损失函数。但是实际上,在训练初期,或者得到一个非常好的判别器的时候,那么这个数值是非常小的,也就是判别器的性能非常好,那么这种情况下,就不得不使用其他的方法,而论文作者提出的这个log(D_fake)就很合适,只有在最后的时候才能变小(当然这个损失函数也有缺点,WGAN作者提出)。这样的逻辑就能顺利了。


在文章[1]提供的GAN源码中,针对损失函数,他还提供了另外一种方式。

D_loss_real = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
	logits=D_logit_real, labels=tf.ones_like(D_logit_real)))
D_loss_fake = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
	logits=D_logit_fake, labels=tf.zeros_like(D_logit_fake)))
D_loss = D_loss_real + D_loss_fake
G_loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(
	logits=D_logit_fake, labels=tf.ones_like(D_logit_fake)))

这个跟前面说的是一样的,只不过是使用了tf自己的库而已。那么如果是按照这样来说明的话, 不管是判别器或者生成器的损失函数,都应该是越来越小为好。产生这种情况的原因,其实本质上是因为他没有像keras一样生成带有标签的数据,而是以一种隐式的方式说明了结果是1还是0。同时也告诉了我,我之前的时候训练一个非常简单的时序数据的GAN时候,那个损失函数肯定是不对的,他们最终应该是收敛于一个数值,而不是一直增加。

后记

本篇文章后面的地方写的很短,就是因为没有办法从实际意义上来完整理解,同时代码也不一样,导致了现在的结果。本身就是要学习wgan的损失函数的,但是因为不理解tf的代码,所以大部分时间都在学习这部分内容。还有一些内容没有记录。这里埋个坑。
Wasserstein GAN implementation in TensorFlow and Pytorch
Building a simple Generative Adversarial Network (GAN) using TensorFlow

参考

[1]Generative Adversarial Nets in TensorFlow
[2]GAN: 原始损失函数详解

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

GAN的编写 - tensorflow形式(tensorflow与GAN同学习,重点分析训练过程) 的相关文章

  • 嵌套字典中的 Django 模板

    我正在使用 Django 模板 并且遇到了嵌套字典的一个问题 Dict result dict type 0 file name abc count 0 type 1 file name xyz count 50 我的 HTML 文件中的模
  • 使用 Python 创建 MIDI

    本质上 我正在尝试从头开始创建 MIDI 并将它们放到网上 我对不同的语言持开放态度 但更喜欢使用Python 两种语言之一 如果这有什么区别的话 并且想知道我应该使用哪个库 提前致谢 看起来这就是您正在寻找的 适用于 Python 的简单
  • 从 Python 下载/安装 Windows 更新

    我正在编写一个脚本来自动安装 Windows 更新 我可以将其部署在多台计算机上 这样我就不必担心手动更新它们 我想用 Python 编写这个 但找不到任何关于如何完成此操作的信息 我需要知道如何搜索更新 下载更新并从 python 脚本安
  • 在Python中如何获取字典的部分视图?

    是否有可能获得部分视图dict在Python中类似于pandasdf tail df head 说你有很长一段时间dict 而您只想检查某些元素 开头 结尾等 dict 就像是 dict head 3 To see the first 3
  • 从sklearn PCA获取特征值和向量

    如何获取 PCA 应用程序的特征值和特征向量 from sklearn decomposition import PCA clf PCA 0 98 whiten True converse 98 variance X train clf f
  • 无故运行测试时 PyCharm 抛出“AttributeError: 'module' object has no attribute”

    因此 我有一个 Django REST Framework 项目 有一天它无法在 PyCharm 中运行测试 从命令行我可以使用它们来运行它们paver or the manage py直接地 曾经有一段时间 当我们没有在文件顶部导入类的超
  • 字符串中的注释和注释中的字符串

    我正在尝试使用 Python 和 Regex 计算 C 代码中包含的注释中的字符数 但没有成功 我可以先删除字符串以删除字符串中的注释 但这也会删除注释中的字符串 结果会很糟糕 是否有机会通过使用正则表达式来询问不匹配注释中的字符串 反之亦
  • “一旦获取切片就无法更新查询”。最佳实践?

    由于我的项目的性质 我发现自己不断地从查询集中取出切片 如下所示 Thread objects filter board requested board id order by updatedate 10 但这给我带来了实际对我选择的元素进
  • 将二维数组放入 Pandas 系列中

    我有一个 2D Numpy 数组 我想将其放入 pandas 系列 而不是 DataFrame 中 gt gt gt import pandas as pd gt gt gt import numpy as np gt gt gt a np
  • 如何根据 HTTP 请求使用 Python 和 Flask 执行 shell 命令并流输出?

    下列的这个帖子 https stackoverflow com questions 15092961 how to continuously display python output in a webpage 我能够tail f网页的日志
  • 在相同任务上,Keras 比 TensorFlow 慢

    我正在使用 Python 运行斩首 DCNN 本例中为 Inception V3 来获取图像特征 我使用的是 Anaconda Py3 6 和 Windows7 使用 TensorFlow 时 我将会话保存在变量中 感谢 jdehesa 并
  • 如何在 Django 中使用基于类的视图创建注册视图?

    当我开始使用 Django 时 我几乎使用 FBV 基于函数的视图 来处理所有事情 包括注册新用户 但当我更深入地研究项目时 我意识到基于类的视图通常更适合大型项目 因为它们更干净且可维护 但这并不是说 FBV 不是 无论如何 我将整个项目
  • Pandas 堆积条形图中元素的排序

    我正在尝试绘制有关某个地区 5 个地区的家庭在特定行业赚取的收入比例的信息 我使用 groupby 按地区对数据框中的信息进行排序 df df orig groupby District Portion of income value co
  • `pyqt5'错误`元数据生成失败`

    我正在尝试安装pyqt5使用带有 M1 芯片和 Python 3 9 12 的 mac 操作系统 我怀疑M1芯片可能是原因 我收到一个错误metadata generation failed 最小工作示例 directly in the t
  • 使用 pybtex 将 bibtex 转换为格式化的 HTML 参考书目,例如哈佛风格

    我正在使用 Django 并将 bibtex 存储在我的模型中 并且希望能够以格式化 HTML 字符串的形式向我的视图传递引用 使其看起来像哈佛引用样式 使用中描述的方法Pybtex 无法识别 bibtex 条目 https stackov
  • Flask 应用程序的测试覆盖率不起作用

    您好 想在终端的 Flask 应用程序中测试 删除路由 我可以看到测试已经过去 它说 test user delete test app LayoutTestCase ok 但是当我打开封面时 它仍然是红色的 这意味着没有覆盖它 请有人向我
  • Python问题:打开和关闭文件返回语法错误

    大家好 我发现了这个有用的 python 脚本 它允许我从网站获取一些天气数据 我将创建一个文件和其中的数据集 有些东西不起作用 它返回此错误 File
  • bs4 `next_sibling` VS `find_next_sibling`

    我在使用时遇到困难next sibling 并且类似地与next element 如果用作属性 我不会得到任何返回 但如果用作find next sibling or find next 然后就可以了 来自doc https www cru
  • [cocos2d-x]当我尝试在 Windows 10 中运行“python android-build.py -p 19 cpp-tests”时出现错误

    当我尝试运行命令时python android build p cpp tests 我收到如图所示的错误 在此之前 我收到了另一条关于 Android SDK Tools 版本兼容性的错误消息 所以 我只是将 sdk 版本从 26 0 0
  • python 日志记录会刷新每个日志吗?

    当我使用标准模块将日志写入文件时logging 每个日志会分别刷新到磁盘吗 例如 下面的代码会将日志刷新 10 次吗 logging basicConfig level logging DEBUG filename debug log fo

随机推荐

  • /usr/lib64/sa/sa1脚本解释

    usr lib64 sa sa1脚本解释 前言 脚本原文 脚本解释 附 前言 这个脚本是 Linux 系统上的 sysstat 工具的一部分 在 etc cron d sysstat这个定时任务下执行 用来收集系统性能数据 需要配合 etc
  • 休眠后网络无法自动连接——网卡属性没有电源管理选项

    问题描述 1 每次休眠过后网卡都是无法连接网络的状态 需要手动禁用 gt 开启网卡后才会恢复正常 2 同时网卡属性里没有电源管理选项 环境 Win10 网卡设备 realtek pcie gbe family controller 解决办法
  • 遗传算法超详细图解

    遗传算法 Genetic Algorithm 顾名思义 是一种基于自然选择原理和自然遗传机制的启发式搜索算法 该算法通过模拟自然界中生物遗传进化的自然机制 选择 交叉和变异操作 将好的遗传基因 最优目标 不断遗传给子代 使得后代产生最优解的
  • webpack对js文件和eslint做缓存处理

    一 什么是webpack的cache Webpack的缓存通常是指模块缓存和构建缓存 1 模块缓存 通过缓存模块的内容 可以避免重复读取和解析同一个模块的开销 Webpack默认是开启模块缓存的 即第一次编译时会将已经加载的模块信息缓存到内
  • MAX30102血氧模块检测心率和血氧

    1 完成 CubeMX初始化配置 1 1 利用CubeMX完成HAL库工程模板和初始化 通过选择芯片型号创建CubeMX工程 在弹出的对话框中输入开发板上的芯片型号 STM32F103RB 在右侧筛选栏中选择Tx型 即开发板上芯片所用的LQ
  • 7个高清图片素材网,免费/可商用

    1 菜鸟图库 https www sucai999 com pic html v NTYwNDUx 菜鸟图库是一个综合性素材网站 这里面有很多设计 图片 视频 音频等素材 图片素材全部都是高清无水印 基本都能免费下载 还有部分素材是可以商用
  • c#输出当前日期和当前时间_如何在C#中的当前日期时间添加小时数?

    我们在C 中使用DateTime类的AddHours 方法 Syntax 句法 DateTime DateTime AddHours double 以下C 代码在当前日期时间添加小时数 using System namespace Cons
  • 父类和子类

    尽管很多知名译本都把C 面向对象里有继承关系的类称作基类和派生类 但人们很多口语化的表达里还是叫他们父类和子类 毕竟 你继承了我嘛 非亲非故的 谁让你继承 恰逢今天父亲节 我们就来聊聊C 里对父亲和儿子这一关系的设计 读程序 品人生 什么东
  • 优雅/粗暴地关闭TCP连接--close-shutdown的选择

    一个 TCP 连接需要经过三次握手进入数据传输阶段 最后来到连接关闭阶段 在最后的连接关闭阶段 我们需要重点关注的是 半连接 状态 因为 TCP 是双向的 这里说的方向 指的是数据流的写入 读出的方向 比如客户端到服务器端的方向 指的是客户
  • Lua封装延时执行函数

    延时执行函数 function delayTimeGuideEvent target func times 延迟时间执行函数 local delaytime 1 if times then delaytime times end getRo
  • Spring入门学习—Spring IOC

    一 什么是Spring Spring是一个轻量级的IOC DI和AOP容器的开源框架 目标 使现有技术更加易用 推进编码最佳实践 内容 IOC容器 AOP实现 数据访问支持 简化JDBC ORM框架 声明式事务 Web集成 设计理念 面向B
  • 平凡的世界

    1975年的二三月间 一个平平常常的日子 细蒙蒙的雨丝夹着一星半点的雪花 正纷纷淋淋地向大地飘洒着 时令已快到惊蛰 雪当然再不会存留 往往还没等落地 就已经消失得无影无踪了 黄土高原严寒而漫长的冬天 看来就要过去 但那真正温暖的春天 还远远
  • gitcode代码仓库的基本使用

    gitcode代码仓库的基本使用 一 gitcode官网简介 二 本地配置 1 安装git工具 2 配置本地git信息 3 查看git个人信息 二 创建本地仓库 1 创建本地工作区 2 将文件放入暂存区 3 将暂存区文件放入本地仓库 4 查
  • AutoML-第一章 超参数优化

    第一章 超参数优化 摘要 最近对具有许多超参数的复杂且计算成本很高的机器学习模型 例如自动化机器学习 AutoML 框架和深度神经网络 的兴趣引起了对超参数优化 HPO 的重新研究 在本章中 我们概述了 HPO 最主要的方法 我们首先讨论基
  • LinkedList 对比 ArrayList 的区别

    LinkedList 底层是双向链表 基于双向链表 无需连续内存 随机访问慢 要沿着链表遍历 头尾插入删除性能高 占用内存多 ArrayList 底层是数组 5 基于数组 需要连续内存 6 随机访问快 指根据下标访问 7 尾部插入 删除性能
  • 为什么32位的计算机内存最多4G

    1 计算机的最小存储单元 bit 位 一个bit用于存放一个二进制数 内存的单位 Byte 一个Byte 8bit 2 计算机会给每一个单位的内存 1Byte 分配一个地址 CPU是通过内存地址来调用内存中的数据的 调用方式是直接寻址 直接
  • ResNet50 结构

    ResNet有2个基本的block 一个是Identity Block 输入和输出的dimension是一样的 所以可以串联多个 另外一个基本block是Conv Block 输入和输出的dimension是不一样的 所以不能连续串联 它的
  • centos7 无法启动网络(systemctl start network.service )错误解决办法

    大家安装Centos7 系统后 可能会出现 网卡无法自动启动 需要在图形界面点击有线链接 才能正常上网 在这里就简单说下NetworkManager service 和network service的区别 前者是图像化管理网络连接的网络服务
  • SpringBoot定时任务设置

    1 主启动类加上注解 开启定时任务 EnableScheduling 2 创建定时任务类 import org springframework beans factory annotation Autowired import org sp
  • GAN的编写 - tensorflow形式(tensorflow与GAN同学习,重点分析训练过程)

    20200901 本文完成于20200902下午 前面内容还算整洁 越到后面因为都是自己思考的过程 就导致文章越来越乱 就算是把自己思考的过程给记录下来吧 0 引言 之前的时候对keras框架编写的GAN网络进行了介绍 GAN的学习 训练过