深度学习:透过神经网络的内在灵魂与柏拉图的哲学理念 输入数字反向的产生数字图像

以神经网络为基础的深度学习,它最大的作用就是让计算机能求解那些没有明确规则或定义的问题,例如你根本无法制定出一系列明确的规则或步骤去让计算机识别一幅图像中的内容是什么,人工智能最大的强项就是让计算机能处理那些模糊不清,几乎无法用明确的规则或步骤来描述的问题。

一个受过大量数据训练的神经网络,给定领域内的图像表示什么内容,此时它就像一个黑盒子,把数据从一端输入,然后结果自动从另一端输出,你根本不知道他内部的运行机制。如果我们只在乎得到正确的结果,那么无论神经网络的内部机理如何复杂,我们都无需关心。如果我们想知道神经网络是如何学习输入数据,并总结出某种特定规律来,那么我们现在能知道的,就是网络会不断的调整链路上权值。

由于神经网络模拟的是大脑思维方式,人的大脑有意识,那神经网络是否也有自己的”意识“呢?原来神经网络的工作流程如下:
数字图片 -> 神经网络 -> 数字
如果我们反其道而行之,给定一个数字,让神经网络把该数字对应的”图片“给画出来,那么我们就可以窥探神经网络是如何通过自己的”意识“来认识这个世界了,也就是我们把上面流程改为:
数字图片<-神经网络<-数字
通过上面的逆流程,我们就可以大概了解世界在神经网络中的样子。
我们已经知道,神经网络得出的结果是先把输入信号与链路权重做乘机后求和,然后在对求和结果应用激活函数,所的到的结果就是神经节点输出的信号。反过来,我们拿到最终输出结果后,先做激活函数的逆运算,得到信号与权重的乘机和,然后再除以链路权重还原回各个信号分量,将这些信号分量合成一幅图像,我们就可以得知,神经网络是如何看待这个世界的。

我们知道网络节点的激活函数如下:
这里写图片描述
要把里面的x解出来,我们就需要下面的公式:
这里写图片描述
在python中,它对应的代码为scipy.special.logit(),于是利用这个公式,我们用如下代码把结果反解出对应的图片,相应的实现代码如下:

import scipy.special
import numpy

class  NeuralNetWork:
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        #初始化网络,设置输入层,中间层,和输出层节点数
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes

        #设置学习率
        self.lr = learningrate
        '''
        初始化权重矩阵,我们有两个权重矩阵,一个是wih表示输入层和中间层节点间链路权重形成的矩阵
        一个是who,表示中间层和输出层间链路权重形成的矩阵
        '''
        self.wih = numpy.random.rand(self.hnodes, self.inodes) - 0.5
        self.who = numpy.random.rand(self.onodes, self.hnodes) - 0.5

        self.activation_function = lambda x:scipy.special.expit(x)

        #设置激活函数的反函数
        self.inverse_activation_function = lambda x:scipy.special.logit(x)
        pass
    def  train(self, inputs_list, targets_list):
        #根据输入的训练数据更新节点链路权重
        '''
        把inputs_list, targets_list转换成numpy支持的二维矩阵
        .T表示做矩阵的转置
        '''
        inputs = numpy.array(inputs_list, ndmin=2).T
        targets = numpy.array(targets_list, ndmin=2).T
        #计算信号经过输入层后产生的信号量
        hidden_inputs = numpy.dot(self.wih, inputs)
        #中间层神经元对输入的信号做激活函数后得到输出信号
        hidden_outputs = self.activation_function(hidden_inputs)
        #输出层接收来自中间层的信号量
        final_inputs = numpy.dot(self.who, hidden_outputs)
        #输出层对信号量进行激活函数后得到最终输出信号
        final_outputs = self.activation_function(final_inputs)

        #计算误差
        output_errors = targets - final_outputs
        hidden_errors = numpy.dot(self.who.T, output_errors)
        #根据误差计算链路权重的更新量,然后把更新加到原来链路权重上
        self.who += self.lr * numpy.dot((output_errors * final_outputs *(1 - final_outputs)),
                                       numpy.transpose(hidden_outputs))
        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1 - hidden_outputs)),
                                       numpy.transpose(inputs))

        pass
    def  query(self, inputs):
        #根据输入数据计算并输出答案
        #计算中间层从输入层接收到的信号量
        hidden_inputs = numpy.dot(self.wih, inputs)
        #计算中间层经过激活函数后形成的输出信号量
        hidden_outputs = self.activation_function(hidden_inputs)
        #计算最外层接收到的信号量
        final_inputs = numpy.dot(self.who, hidden_outputs)
        #计算最外层神经元经过激活函数后输出的信号量
        final_outputs = self.activation_function(final_inputs)
        return final_outputs
    def backQuery(self, targets_list):
         # 将结果向量转置以便反解出输入信号量
        final_outputs = numpy.array(targets_list, ndmin=2).T

        # 通过激活函数的反函数得到输出层的输入信号
        final_inputs = self.inverse_activation_function(final_outputs)

        # 获取中间层的输出信号
        hidden_outputs = numpy.dot(self.who.T, final_inputs)
        # 将信号量圆整到0.01和0.98之间
        hidden_outputs -= numpy.min(hidden_outputs)
        hidden_outputs /= numpy.max(hidden_outputs)
        hidden_outputs *= 0.98
        hidden_outputs += 0.01

        #通过激活函数的反函数计算中间层获得的输入信号量
        hidden_inputs = self.inverse_activation_function(hidden_outputs)

        # 计算输入层的输出信号量
        inputs = numpy.dot(self.wih.T, hidden_inputs)
        # 将信号量圆整到0.01和0.98之间
        inputs -= numpy.min(inputs)
        inputs /= numpy.max(inputs)
        inputs *= 0.98
        inputs += 0.01
        #input对应的就是输入神经网络的图片像素数组
        return inputs

上面代码跟以前不一样之处就在于多了一个backQuery函数,它接收结果向量,让后反解出向量对应的输入图片,有了上面神经网络后,我们先对其进行训练,得到相应的神经元链路权重:

#初始化网络
input_nodes = 784
hidden_nodes = 100
output_nodes = 10
learning_rate = 0.3
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)
#读入训练数据
#open函数里的路径根据数据存储的路径来设定
training_data_file = open("/Users/chenyi/Documents/人工智能/mnist_train.csv")
trainning_data_list = training_data_file.readlines()
print(len(trainning_data_list))
training_data_file.close()
#加入epocs,设定网络的训练循环次数
epochs = 7
print("begin trainning")

for e in range(epochs):
    #把数据依靠','区分,并分别读入
    for record in trainning_data_list:
        all_values = record.split(',')
        inputs = (numpy.asfarray(all_values[1:]))/255.0 * 0.99 + 0.01
        #设置图片与数值的对应关系
        targets = numpy.zeros(output_nodes) + 0.01
        targets[int(all_values[0])] = 0.99
        n.train(inputs, targets)


print("trainning complete")

有了合适的链路权值后,我们构造一个结果向量,将它输入到网络中,让网络把它认为的向量对应的图像输出来:

label = 8
targets = numpy.zeros(output_nodes) + 0.01
targets[label] = 0.99
print(targets)
image_data = n.backQuery(targets)
#print(image_data.reshape(28,28))
matplotlib.pyplot.imshow(image_data.reshape(28,28), cmap="Greys", interpolation="None")

上面代码构造了一个数字8对应的结果向量,然后传入神经网络看看网络眼中的数字8是什么样子的,上面代码执行后结果如下:

这里写图片描述

没错,上面模糊一片的图案就是神经网络对数组8的理解,我们慢慢观察黑色部分,发觉它确实跟数字8有点像。这个图案让我想起了两千年前古希腊哲学家柏拉图提出一个叫”理型“的哲学概念,它的意思是说,每一个种类的事物,无论其外形如何变幻,他们本身都包含着一种超越时空,永恒不变的抽象属性。举个例子,给一个孩子看一只黑马的图片,然后让他看一只白马的图片,他很容易能认出那是马,也就是说不管黑马白马的外形差异如何,两只马都具备相同的理型叫做”马“,人正是因为感受到马的”理型“,所以不管马的形态如何变幻,人总能认出它是马来,也就是说所有的马都具备同一种抽象的超越时空,永恒不变的性质,正是这个性质将它与其他事物区分开来。

道可道,非常道。理型的概念就是”道可道“中的第一个道,也就是永恒不变的规律,通常情况下,”道“是很难用语言或某种显著方式进行表达的。神经网络通过计算大量的手写数字图片,通过计算抽取出了这些同一类数字图片的共性,这个共性其实就是柏拉图所说的理型,也就是所有手写的数字”8“,都蕴含着某种不变的性质,神经网络就是把这个性质抽取出来的方式,上面那张模糊的图案,可以认为是所有手写数字8的理型,网络读取的图片数量越大,其对理型的把握就越准确。

如此一来”非常道“似乎就不成立了,神经网络的结构以及链路上的权重,就可以用来对”道“进行描述,或者说一切手写数字的”理型“可以用现在我们训练的神经网络来描述。

以神经网络为基础的深度学习模仿人的意识,在一定程度上也跟人的思维哲学有了交互之处,这就是技术发展与人文思想的交相辉映吧。至此我们对神经网络的基本原理说明就告一段落,从下一章开始,我们进入神经网络的实际应用层面。

国际大赛的第一名为Better所夺得 三个月结束时他的EA(自动交易系统) 把本金从$10000增加成$130 475.45 他采用的就是神经网络原理的EA 这使得用神经网络方法做EA成为不少人关注的焦点 这里翻译一篇采用神经网络做EA的不错的示例文章当然附有源码是吸引人的地方 不过也许作者提出了研究神经网络EA的一些思考更为值得注意 作者提出了∶ 1。“如果有飞机,为什么还要教人类去飞?” 意思是研究是经网络不必从零起步。MT4里已有了不错的“遗传算法” 文中介绍了如何利用MT4已有的“遗传算法” 2。大家都说做单子最重要的是“顺势而为”,但更需要解决的是∶ “一个基于趋势的交易系统是不能成功交易在盘整(sideways trends), 也不能识别市场的回调(setbacks)和逆转(reversals.,反向走势)!” 这可是抓到不少人心中的“痒处” ,有多少人不是到了该逆势时没转向而产生亏损呢? 3。训练神经网络需要用多长的历史数据,提出了并不是用的历史数据越长越好,另外也不是训练的间隔越短越好,文中提出了什么情况下有需再训练它。 4。示例当然仅是示例 等等。。 一个朋友看了就觉得不错拿去发表了 这里发表以飨这里的朋友 下面是译文和作者的原文 The problem is stated for this automated trading system (ATS) as follows: (ATS)自动的(智能的,采用神经网络的)交易系统的问题表述如下 Let's consider we have a basic trading system - BTS. It is necessary to create and teach a neural network in order it to do things that cannot be done with the BTS. This must result in creation of a trading system consisting of two combined and mutually complementary BTS and NN (neural network). 如果我们有一个(BTS, basic trading system),同时需要用创建一个神经网络系统并教会它做BTS所不能做的事,按这个思路就是要创建这样一个交易系统∶它由互相补充(配合)的两部分组成,BTS和NN(神经网络)。 Or, the English of this is: There is no need to discover the continents again, they were all discovered. Why to teach somebody to run fast, if we have a car, or to fly, if we have a plane? 呃,英语说,我们不需要再去发现“新大陆”,它们是已经存在的东西!进一步说,如果我们已经有了汽车,那为什么还要教人如何跑得快?如果有飞机,为什么还要教人类去飞? Once we have a trend-following ATS, we just have to teach the neural network in countertrend strategy. This is necessary, because a system intended for trend-based trading cannot trade on sideways trends or recognize market setbacks or reversals. You can, of course, take two ATSes - a trend-following one and a countertrend one - and attach them to the same chart. On the other hand, you can teach a neural network to complement your existing trading system. 一旦有一个趋势交易系统的ATS,我们仅需要教会这个神经网络如何逆势(反趋势)交易的策略。这一点是非常必要的,因为一个基于趋势的交易系统是不能成功交易在盘整(sideways trends),也不能识别市场的回调(setbacks)和逆转(reversals.,反向走势)!当然,你可以采用两个ATS,一个基于“趋势”,一个基于“反趋势”(逆向),然后把它们挂到同一图表上。另一个办法是,你能教会神经网络如何与你现有的系统“互补地”协调工作! For this purpose, we designed a two-layer neural network consisting of two perceptrons in the lower layer and one perceptron in the upper layer. 为实现这个目标,我们设计了一个两层的神经网络,下层有两个感知机(perceptrons)上层有一个感知机。 The output of the neural network can be in one of these three states: 这个神经网络的能输出下列三种状态之一 Entering the market with a long position (Entering)市场是处在多向仓 Entering the market with a short position (Entering)市场是处在空向仓 Indeterminate state 不确定的, (不明确的, 模糊的)状态 Actually, the third state is the state of passing control over to the BTS, whereas in the first two states the trade signals are given by the neural network. 实际上,第三种状态是就把控制权交给BTS,反之前两种状态是交易信号由神经网络给出。 The teaching of the neural network is divided into three stages, each stage for teaching one perceptron. At any stage, the optimized BTS must be present for perceptrons to know what it can do. 神经网络的“教育”分成三步骤,每一步骤“教育”一个感知机,在任何一步骤,这个优化了的BTS必须存在为的是“感知机们”知道它自己能做什么。 The sep***te teaching of perceptrons by a genetic algorithm is determined by the lack of this algorithm, namely: The amount of inputs searched in with the help of such algorithm is limited. However, each teaching stage is coherent and the neural network is not too large, so the whole optimization does not take too much time. 感知机们分别的“教育”由遗传算法来承担,由于这样的算法的缺乏,换句话说,搜索到的这样的算法有限,限制了“输入”(参数变量)的数量(借助这样算法得到的参数变量的值),然而,每一步骤的“教育”是密切配合补充的。(因此效果还是不错),这样这个神经网络不会太大,整个的优化也不会耗费太多的时间。 The very first stage, preceding the teaching of an NN, consists in optimization of the BTS. 在“教育”NN之前的一步是对BTS进行优化。 In order not to lose ourselves, we will record the stage number in the input of the ATS identified as "pass". Identifiers of inputs corresponding with the stage number will and in the number equal to this stage number. 为了不使我们自己也被搞糊涂了,我们将已经测试通过的ATS的输入(参数变量)记录上(”通过”("pass")的步骤号(stage number).,输入s(参数变量)的标识符将和stage number(步骤号)一致(等同)。 Thus, let's start prep***tions for optimization and teaching the NN. Let's set the initial deposit as $1000000 (in order not to create an artificial margin call during optimization) and the input to be optimized as "Balance" in Expert Advisor properties on the tab of "Testing" in the Strategy Tester, and start genetic algorithm. 这样,我们开始对这个NN进行优化和“教育”的准备。存入初始保证金为$100万(以便于在优化期间不产生人为的补充保证金的通知)。Input(参数变量)是按“余额”进行优化,设置EA的Strategy Tester的测试的属性tab为"Testing" 。开始运行遗传算法。 Let's go to the "Inputs" tab of the EA's properties and specify the volume of positions to be opened by assigning the value 1 to the identifier "lots". 在这个EA的开仓量 "lots".的值设为1 lot。 Optimization will be performed according to the model: "Open prices only (fastest method to analyze the bar just completed, only for EAs that explicitly control bar opening)", since this method is available in the ATS algorithm. 从这个ATS算法明确地有效开始,实施优化,所采用复盘模型是∶“仅用开盘价(以最快速的方法分析刚形成的柱线)”。 Stage 1 of optimization. Optimization of the BTS: 优化步骤1,BTS的优化 Set the value 1 for the input "pass". 设置为 1 为这input(参数变量)“为通过”(the input "pass")。 We will optimize only inputs that correspond with the first stage, i.e., that end in 1. Thus, we check only these inputs for optimization, and uncheck all others. 我们仅仅优化步骤1相关的那些inputs(参数变量),即,尾标为 1 的参数变量,于是,我们仅仅测试优化有关的inputs而不测试其他的变量参数 tp1 - TakeProfit of the BTS. It is optimized with the values within the range of 10 to 100, step 1 tp1,BTS的所取的止盈值(TakeProfit)。在step 1,优化的值的范围在10到100, sl1 - StopLoss of the BTS. It is optimized with the values within the range of 10 to 100, step 1 sl1,BTS的所取的止损值(StopLoss)。在step 1,优化的值的范围在10到100 。 p1 - period of CCI used in the BTS. It is optimized with the values within the range of 3 to 100, step 1 pl, 用于BTS的CCI的周期值。在step 1 ,优化的值的范围在 3到100 Stage 2. Teaching the perceptron responsible for short positions: 步骤 2 ,“教育负责管“开空仓”(short positions)的感知机 Set the value 2 (according to the stage number) for the input "pass". 根据步骤的步骤号,设置(input,参数变量) 的"pass"的值为 2。 Uncheck the inputs checked for optimization in the previous stage. Just in case, save in a file the inputs obtained at the previous stage. 不测试那些已经测试过的优化了的以前步骤的inputs.(变量参数)。以防万一,保存以前步骤获得的inputs(变量参数值)到一个文件中去 Check the inputs for optimization according to our rule: their identifiers must end in 2: 根据我们的规则,必须是测试那些是在尾标为 2的inputs(变量参数)。 x12, x22, x32, x42 - weight numbers of the perceptron that recognizes short positions. It is optimized with the values within the range of 0 to 200, step 1 x12, x22, x32, x42 是识别并开空仓的感知机的权重,它们的值在step 1时被优化在范围0 to 200 tp2 - TakeProfit of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1 tp2 (TakeProfit) 是感知机所开的仓的止盈值,它们的值在step 1时被优化在范围10 to 100。 sl2 - StopLoss of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1 sl2 (StopLos) 在 step 1它是感知机所开的仓的止损值,被优化值的范围在 10 to 100 p2 - the period of the values of price difference to be analyzed by the perceptron. It is optimized with the values within the range of 3 to 100, step 1. p2 感知机所分析的价格差的周期值 (iiCCI()函数的一个参数∶period - Averaging period for calculation),在step 1 它的值所优化的范围在3 to 100 Let's start teaching it using optimization with a genetic algorithm. The obtained results are given below: 现在,开始用遗传算法来优化“教育”NN(让它“学习”市场),获得的结果如下∶ Stage 3. Teaching the perceptron responsible for long positions: 步骤 3 “教育”负责开多仓的感知机(“学习”市场)。 Set the value 3 (according to the stage number) for the input "pass". 设置值 3 (根据步骤的步骤号)说明这些input(变量参数)已经“通过”(the input "pass") Uncheck the inputs checked for optimization in the previous stage. Just in case, save in a file the inputs obtained at the previous stage. 同样,不测试,那些已经测试过的优化了的,以前步骤的inputs.(变量参数值),以防万一,保存以前步骤获得的inputs.(变量参数值) 到一个文件中去 Check the inputs for optimization according to our rule: their identifiers must end in 3: 根据我们的规则,优化测试的inputs(变量参数值)必须是尾标为3的那些变量参数。 x13, x23, x33, x43 - weight numbers of the perceptron that recognizes long positions. It is optimized with the values within the range of 0 to 200, step 1. x13, x23, x33, x43是识别多仓的感知机的权重,它们的值在step 1时被优化时得到的范围在0 to 200 tp3 - TakeProfit of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1 tp 3 (TakeProfit) 是感知机所开的仓的“止盈值”,它的值在step 1时被优化时的范围是在10 to 100。 sl3 - StopLoss of positions opened by the perceptron. It is optimized with the values within the range of 10 to 100, step 1 sl3 (StopLoss) 是感知机所开的仓的“止盈值”,它们的值在step 1时被优化为范围是10 to 100。 p3 - the period of the values of price difference to be analyzed by the perceptron . It is optimized with the values within the range of 3 to 100, step 1. p3 --感知机所分析的价差的周期值。它在步骤 1 优化时得到的值的范围是 3 to 100 。 Let's start teaching it using optimization with a genetic algorithm. The obtained results are given below: 启动采用遗传算法的优化来“教育”NN,所获得的结果如下∶ Stage 4 (final). Teaching the first layer, i.e., teaching the perceptron that is in the upper layer: 步骤 4 (最终步骤) “教育”第一层,即“教育”在上层的感知机。 Set the value 4 (according to the stage number) for the input "pass". 根据步骤的步骤号,设置值4 为输入通过(for the input "pass") Uncheck the inputs checked for optimization in the previous stage. Just in case, save in a file the inputs obtained at the previous stage. 不测试那些在之前步骤已经测试过的优化了的“输入” (inputs) (意思是∶已经在之前步骤优化过的变量的参数值就不再优化它们了)。以防万一,将之前步骤获得的这些变量的参数值存到一个文件中去。 Check the inputs for optimization according to our rule: their identifiers must end in 4: 根据我们的规则,只测试优化标识符最后位是4的那些inputs(变量的参数值) x14, x24, x34, x44 - weight numbers of the perceptron of the first layer. It is optimized with the values within the range of 0 to 200, step 1. x14, x24, x34, x44 是第一层感知机参数的权重值。在步骤 1 时它们被优化的值的范围在0 io 200 。 p4 - the period of the values of price difference to be analyzed by the perceptron. It is optimized with the values within the range of 3 to 100, step 1. p4 被感知机分析的价差的值的周期。在步骤 1 它的值的范围被优化在 3 to 100 。 Let's start teaching it using optimization with a genetic algorithm. The obtained results are given below: 采用遗传算法来优化,启动“教育”来教它“学习”。所获得结果如下∶ That's all, the neural network has been taught. 这就是全部,神经网络已经被“教育”了。 The ATS has one more non-optimizable input, mn - Magic Number. It is the identifier of positions for a trading system not to mix its orders with the orders opened manually or by other ATSes. The value of the magic number must be unique and not coincide with the magic numbers of positions that have not been opened by this specific Expert Advisor. 这个ATS有一个不能被优化的input(参数) mn-- Magic Number.(魔法号)它是一个交易系统它所开的仓位的识别符,为的是不和手动开仓或其他ATSes开的仓位混淆。这个Magic Number的值必须是唯一的并且和这个特别的ea尚未开仓的magic numbers不一致。 P.S. The size of the initial deposit is found as the doubled absolute drawdown, i.e., we consider some safety resources for it. 出于保证有一些安全保险的考虑,初始保证金的金额设置是考虑为绝对最大回落的两倍 The EA given in the source codes is not optimized. 这个ea的源代码没有优化。 If you need to replace the built-in BTS with the algorithm of another trading system, you must modify the contents of the function basicTradingSystem(). 如果你需要置换嵌入另一个交易系统算法的BTS,你必须修改BTS功能的内部。 In order not to enter the initial and the final values and the values of steps for optimization, you can take the ready file combo.set, place it in the folder tester MT4, and upload to the EA's properties in Tester. 以便于不输入优化时的初值,终值和步长,你可采用已备好的combo.set文件,把它放置到MT4的 tester 目录并加载这个ea的属性(properties)到Strategy Tester。 Re-optimization of the EA is to be performed at a weekend, i.e., on Saturday or on Sunday, but only if the results of the preceding week were unprofitable. The presence of losses means that the market has changed, and the re-optimization is necessary. The presence of profits means that the ATS does not need any re-optimization and recognizes market patterns quite well. 这个ea的再优化可在周末进行,即周六和周日,但仅在前面一周的结果是不盈利的。亏损的出现意味着市场已经改变,于是需要重新优化,若是仍然获利意味着这个ATS不需要重新优化,它对市场目前的模型的识别继续有效! 5 comments Subscribe to discussion sstef wrote: backtests seems ok, how about forward tests ? Try independet without me. You all have for original forward and other tests: open source, tester, head and hands. reply 08.03.2008 08:57 Reshetov thanks a lot Reshetov, very simple but very powerful, i have never think about this idea, backtests seems ok, how about forward tests ? reply 07.03.2008 23:42 sstef tws0124 wrote: What is the number of pass? Try test for pass value of 1, 2, 3 and 4 What is best of the best, that use (right solution: pass = 4) reply 07.03.2008 10:45 Reshetov All the optimization is completed, now I use it by live account, What is the number of pass? Sorry,bad English...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zqx951102

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值