《Natural Evolution Strategy (NES).py》详解

"""
The basic idea about Nature Evolution Strategy with visualation.

Visit my tutorial website for more: https://mofanpy.com/tutorials/

Dependencies:
Tensorflow >= r1.2
numpy
matplotlib
"""
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.contrib.distributions import MultivariateNormalFullCovariance

DNA_SIZE = 2         # parameter (solution) number
N_POP = 20           # population size
N_GENERATION = 100   # training step
LR = 0.02            # learning rate


# fitness function
def get_fitness(pred): return -((pred[:, 0])**2 + pred[:, 1]**2)


# 在 TensorFlow 中,所有在节点之间传递的数据都为 Tensor 对象。
# 也就是说,Tensor本身是不存储数据的,创建一个Tensor实际就是声明了一个数据节点。只有开启Session进行运算的时候,才会获取到数据。

# build multivariate distribution  建立多元分布
# tf.random_normal(shape, mean, stddev, dtype, seed, name),生成正太分布随机值
# shape:表示生成随机数的维度;mean:正太分布的均值,默认为0;stddev:正太分布的标准差;dtype:生成正太分布数据的类型
# seed:一个整数,当设置之后,每次生成的随机数都一样;name:正太分布的名字
# tf.Variable()函数用于创建变量(Variable),变量是一个特殊的张量(),其可以是任意的形状和类型的张量。
# 2表示的横纵坐标2个指标,13为正态分布的均值,1为正态分布的标准差。
mean = tf.Variable(tf.random_normal([2, ], 13., 1.), dtype=tf.float32)
# print('tf.random_normal([2, ], 13., 1.):\t' + str(tf.random_normal([2, ], 13., 1.)))
# print('mean:\t' + str(mean))

# cov为方差
# tf.eye 它用于创建指定行和列的单位矩阵。形状为 [m, n] 的单位矩阵由所有对角线元素的值 1 和其余位置的值 0 组成。
cov = tf.Variable(5. * tf.eye(DNA_SIZE), dtype=tf.float32)

# 建立tensorflow的图纸,mean是生成的点,cov是方差
mvn = MultivariateNormalFullCovariance(loc=mean, covariance_matrix=cov)
# 从mvn分布中抽取样本
make_kid = mvn.sample(N_POP)                                    # sampling operation
# print('tf.eye(DNA_SIZE):\t' + str(tf.eye(DNA_SIZE)))
# print('mvn:\t' + str(mvn))
# print('make_kid:\t' + str(make_kid))

# compute gradient and update mean and covariance matrix from sample and fitness
# tf.placeholder(dtype, shape=None, name=None) 为占位符
# 孩子的适应度
tfkids_fit = tf.placeholder(tf.float32, [N_POP, ])
# 孩子的DNA
tfkids = tf.placeholder(tf.float32, [N_POP, DNA_SIZE])
# log_prob返回密度或概率的对数,损失函数 ylna+(1-y)ln(1-a)
# tf.reduce_mean()用于计算tensor(张量)沿着指定的数轴(即tensor的某一维度)上的平均值,用作降维或者计算tensor的平均值。
# 适应度越高下降得越快
loss = -tf.reduce_mean(mvn.log_prob(tfkids)*tfkids_fit)         # log prob * fitness
train_op = tf.train.GradientDescentOptimizer(LR).minimize(loss) # compute and apply gradients for mean and cov

# 搭建图纸,激活节点
sess = tf.Session()
sess.run(tf.global_variables_initializer())                     # initialize tf variables

# something about plotting (can be ignored)
n = 300
x = np.linspace(-20, 20, n)
# X, Y = np.meshgrid(x, y) 代表的是将x中每一个数据和y中每一个数据组合生成很多点,然后将这些点的x坐标放入到X中,y坐标放入Y中,并且相应位置是对应的
X, Y = np.meshgrid(x, x)
# np.zeros_like(a)的目的是构建一个与a同维度的数组,并初始化所有变量为零
Z = np.zeros_like(X)
for i in range(n):
    for j in range(n):
        Z[i, j] = get_fitness(np.array([[ x[i], x[j] ]]))

# plt.contourf用来画出不同分类的边界线
plt.contourf(X, Y, -Z, 100, cmap=plt.cm.rainbow)
plt.ylim(-20, 20)
plt.xlim(-20, 20)
plt.ion()

# training
for g in range(N_GENERATION):
    # if g % 10 == 0:
    #     plt.contourf(X, Y, -Z, 100, cmap=plt.cm.rainbow);
    # plt.ylim(-20, 20);
    # plt.xlim(-20, 20);
    kids = sess.run(make_kid)
    kids_fit = get_fitness(kids)
    sess.run(train_op, {tfkids_fit: kids_fit, tfkids: kids})    # update distribution parameters

    # plotting update
    if 'sca' in globals(): sca.remove()
    sca = plt.scatter(kids[:, 0], kids[:, 1], s=30, c='k');plt.pause(0.01)
    print('-'*20 + str(g))

print('Finished'); plt.ioff(); plt.show()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值