当前位置: 首页 > news >正文

从零开始训练神经网络

用Keras实现一个简单神经网络

Keras:
Keras是由纯python编写的基于theano/tensorflow的深度学习框架。
Keras是一个高层神经网络API,支持快速实验,能够把你的idea迅速转换为结果,如果有如下需 求,可以优先选择Keras:
a)简易和快速的原型设计(keras具有高度模块化,极简,和可扩充特性)
b)支持CNN和RNN,或二者的结合
c)无缝CPU和GPU切换

[1]
'''
将训练数据和检测数据加载到内存中(第一次运行需要下载数据,会比较慢):
train_images是用于训练系统的手写数字图片;
train_labels是用于标注图片的信息;
test_images是用于检测系统训练效果的图片;
test_labels是test_images图片对应的数字标签。
'''
from tensorflow.keras.datasets import mnist
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
print('train_images.shape = ',train_images.shape)
print('tran_labels = ', train_labels)
print('test_images.shape = ', test_images.shape)
print('test_labels', test_labels)
'''
1.train_images.shape打印结果表明,train_images是一个含有60000个元素的数组.
数组中的元素是一个二维数组,二维数组的行和列都是28.
也就是说,一个数字图片的大小是28*28.
2.train_lables打印结果表明,第一张手写数字图片的内容是数字5,第二种图片是数字0,以此类推.
3.test_images.shape的打印结果表示,用于检验训练效果的图片有10000张。
4.test_labels输出结果表明,用于检测的第一张图片内容是数字7,第二张是数字2,依次类推。
'''[2]
'''
把用于测试的第一张图片打印出来看看
'''
digit = test_images[0]
import matplotlib.pyplot as plt
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()[3]
'''
使用tensorflow.Keras搭建一个有效识别图案的神经网络,
1.layers:表示神经网络中的一个数据处理层。(dense:全连接层)
2.models.Sequential():表示把每一个数据处理层串联起来.
3.layers.Dense(…):构造一个数据处理层。
4.input_shape(28*28,):表示当前处理层接收的数据格式必须是长和宽都是28的二维数组,
后面的“,“表示数组里面的每一个元素到底包含多少个数字都没有关系.
'''
from tensorflow.keras import models
from tensorflow.keras import layersnetwork = models.Sequential()
network.add(layers.Dense(512, activation='relu', input_shape=(28*28,)))
network.add(layers.Dense(10, activation='softmax'))network.compile(optimizer='rmsprop', loss='categorical_crossentropy',metrics=['accuracy'])[4]               
'''
在把数据输入到网络模型之前,把数据做归一化处理:
1.reshape(60000, 28*28):train_images数组原来含有60000个元素,每个元素是一个28行,28列的二维数组,
现在把每个二维数组转变为一个含有28*28个元素的一维数组.
2.由于数字图案是一个灰度图,图片中每个像素点值的大小范围在0到255之间.
3.train_images.astype(“float32”)/255 把每个像素点的值从范围0-255转变为范围在0-1之间的浮点值。
'''
train_images = train_images.reshape((60000, 28*28))
train_images = train_images.astype('float32') / 255test_images = test_images.reshape((10000, 28*28))
test_images = test_images.astype('float32') / 255'''
把图片对应的标记也做一个更改:
目前所有图片的数字图案对应的是0到9。
例如test_images[0]对应的是数字7的手写图案,那么其对应的标记test_labels[0]的值就是7。
我们需要把数值7变成一个含有10个元素的数组,然后在第8个元素设置为1,其他元素设置为0。
例如test_lables[0] 的值由7转变为数组[0,0,0,0,0,0,0,1,0,0] ---one hot
'''
from tensorflow.keras.utils import to_categorical
print("before change:" ,test_labels[0])
train_labels = to_categorical(train_labels)
test_labels = to_categorical(test_labels)
print("after change: ", test_labels[0])[5]
'''
把数据输入网络进行训练:
train_images:用于训练的手写数字图片;
train_labels:对应的是图片的标记;
batch_size:每次网络从输入的图片数组中随机选取128个作为一组进行计算。
epochs:每次计算的循环是五次
'''
network.fit(train_images, train_labels, epochs=5, batch_size = 128)[6]
'''
测试数据输入,检验网络学习后的图片识别效果.
识别效果与硬件有关(CPU/GPU).
'''
test_loss, test_acc = network.evaluate(test_images, test_labels, verbose=1)
print(test_loss) 
print('test_acc', test_acc)[7]
'''
输入一张手写数字图片到网络中,看看它的识别效果
'''
(train_images, train_labels), (test_images, test_labels) = mnist.load_data()
digit = test_images[1]
plt.imshow(digit, cmap=plt.cm.binary)
plt.show()
test_images = test_images.reshape((10000, 28*28))
res = network.predict(test_images)for i in range(res[1].shape[0]):if (res[1][i] == 1):print("the number for the picture is : ", i)break

从零开始训练神经网络

网络的最终目标是,输入一张手写数字图片后,网络输出该图片对应的数字。
我们的代码要导出三个接口,分别完成以下功能:

  1. 初始化initialisation,设置输入层,中间层,和输出层的节点数。
  2. 训练train:根据训练数据不断的更新权重值
  3. 查询query,把新的数据输入给神经网络,网络计算后输出答案。(推理)
# NeuralNetWork_init.py
[1]
'''
我们先给出如下代码框架:
'''
class  NeuralNetWork:def __init__(self):#初始化网络,设置输入层,中间层,和输出层节点数passdef  train(self):#根据输入的训练数据更新节点链路权重passdef  query(self):#根据输入数据计算并输出答案pass[2]
'''
我们先完成初始化函数,我们需要在这里设置输入层,中间层和输出层的节点数,这样就能决定网络的形状和大小。
当然我们不能把这些设置都写死,而是根据输入参数来动态设置网络的形态。
由此我们把初始化函数修正如下:
'''
class  NeuralNetWork:def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate#passdef  train(self):#根据输入的训练数据更新节点链路权重passdef  query(self):#根据输入数据计算并输出答案pass[3]
'''
此处举例说明:
如此我们就可以初始化一个3层网络,输入层,中间层和输出层都有3个节点
'''
input_nodes = 3
hidden_nodes = 3
output_nodes = 3learning_rate = 0.3
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)[4]
'''
初始化权重矩阵。
由于权重不一定都是正的,它完全可以是负数,因此我们在初始化时,把所有权重初始化为-0.5到0.5之间
'''
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate'''初始化权重矩阵,我们有两个权重矩阵,一个是wih表示输入层和中间层节点间链路权重形成的矩阵一个是who,表示中间层和输出层间链路权重形成的矩阵'''self.wih = numpy.random.rand(self.hnodes, self.inodes) - 0.5self.who = numpy.random.rand(self.onodes, self.hnodes) - 0.5pass[5]
'''
接着我们先看query函数的实现,它接收输入数据,通过神经网络的层层计算后,在输出层输出最终结果。
输入数据要依次经过输入层,中间层,和输出层,并且在每层的节点中还得执行激活函数以便形成对下一层节点的输出信号。
我们知道可以通过矩阵运算把这一系列复杂的运算流程给统一起来。
'''
import numpydef  query(self, inputs):#根据输入数据计算并输出答案hidden_inputs = numpy.dot(self.wih, inputs)pass[6]
'''
hidden是个一维向量,每个元素对应着中间层某个节点从上一层神经元传过来后的信号量总和.
于是每个节点就得执行激活函数,得到的结果将作为信号输出到下一层.
sigmod函数在Python中可以直接调用,我们要做的就是准备好参数。
我们先把这个函数在初始化函数中设定好,
'''
import scipy.specialclass  NeuralNetWork:def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate'''初始化权重矩阵,我们有两个权重矩阵,一个是wih表示输入层和中间层节点间链路权重形成的矩阵一个是who,表示中间层和输出层间链路权重形成的矩阵'''self.wih = numpy.random.rand(self.hnodes, self.inodes) - 0.5self.who = numpy.random.rand(self.onodes, self.inodes) - 0.5'''scipy.special.expit对应的是sigmod函数.lambda是Python关键字,类似C语言中的宏定义.我们调用self.activation_function(x)时,编译器会把其转换为spicy.special_expit(x)。'''self.activation_function = lambda x:scipy.special.expit(x)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)print(final_outputs)return final_outputs

可运行代码

import scipy.special
import numpyclass  NeuralNetWork:def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):#初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.onodes = outputnodes#设置学习率self.lr = learningrate'''初始化权重矩阵,我们有两个权重矩阵,一个是wih表示输入层和中间层节点间链路权重形成的矩阵一个是who,表示中间层和输出层间链路权重形成的矩阵'''self.wih = numpy.random.rand(self.hnodes, self.inodes) - 0.5self.who = numpy.random.rand(self.onodes, self.hnodes) - 0.5'''scipy.special.expit对应的是sigmod函数.lambda是Python关键字,类似C语言中的宏定义,当我们调用self.activation_function(x)时,编译器会把其转换为spicy.special_expit(x)。'''self.activation_function = lambda x:scipy.special.expit(x)passdef  train(self):#根据输入的训练数据更新节点链路权重passdef  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)print(final_outputs)return final_outputs'''
我们尝试传入一些数据,让神经网络输出结果试试.
程序当前运行结果并没有太大意义,但是至少表明,我们到目前为止写下的代码没有太大问题,
'''
input_nodes = 3
hidden_nodes = 3
output_nodes = 3learning_rate = 0.3
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)
n.query([1.0, 0.5, -1.5])

实现网络训练功能
自我训练过程分两步:

  1. 第一步是计算输入训练数据,给出网络的计算结果,这点跟我们前面实现的query()功能很像。
  2. 第二步是将计算结果与正确结果相比对,获取误差,采用误差反向传播法更新网络里的每条 链路权重。

获取训练数据及预处理
接下来我们就得拿实际数据来训练我们的神经网络了。
我们要做的是读取训练数据,以及数据的预处理(归一化)

启动网络,进行训练
网络的最终目标是,输入一张手写数字图片后,网络输出该图片对应的数字。 由于网络需要从0到9一共十个数字中挑选出一个,于是我们的网络最终输出层应该有十个节点,每 个节点对应一个数字。

假设图片对应的是数字0,那么输出层网络中,第一个节点应该输出一个高百分比,其他节点输出低 百分比,如果图片对应的数字是9,那么输出层最后一个节点应该输出高百分比,其他节点输出低百 分比。

[1]
'''
训练过程分两步:
第一步是计算输入训练数据,给出网络的计算结果,这点跟我们前面实现的query()功能很像。
第二步是将计算结果与正确结果相比对,获取误差,采用误差反向传播法更新网络里的每条链路权重。我们先用代码完成第一步.inputs_list:输入的训练数据;
targets_list:训练数据对应的正确结果。
'''
def  train(self, inputs_list, targets_list):#根据输入的训练数据更新节点链路权重'''把inputs_list, targets_list转换成numpy支持的二维矩阵.T表示做矩阵的转置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_list, nmin=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)[2]
'''
上面代码根据输入数据计算出结果后,我们先要获得计算误差.
误差就是用正确结果减去网络的计算结果。
在代码中对应的就是(targets - final_outputs).
'''
def  train(self, inputs_list, targets_list):#根据输入的训练数据更新节点链路权重'''把inputs_list, targets_list转换成numpy支持的二维矩阵.T表示做矩阵的转置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = numpy.array(targets_list, nmin=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_outputshidden_errors = numpy.dot(self.who.T, output_errors*final_outputs*(1-final_outputs))#根据误差计算链路权重的更新量,然后把更新加到原来链路权重上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[3]
'''
使用实际数据来训练我们的神经网络
'''
#open函数里的路径根据数据存储的路径来设定
data_file = open("dataset/mnist_test.csv")
data_list = data_file.readlines()
data_file.close()
len(data_list)
data_list[0]
'''
这里我们可以利用画图.py将输入绘制出来
'''[4]
'''
从绘制的结果看,数据代表的确实是一个黑白图片的手写数字。
数据读取完毕后,我们再对数据格式做些调整,以便输入到神经网络中进行分析。
我们需要做的是将数据“归一化”,也就是把所有数值全部转换到0.01到1.0之间。
由于表示图片的二维数组中,每个数大小不超过255,由此我们只要把所有数组除以255,就能让数据全部落入到0和1之间。
有些数值很小,除以255后会变为0,这样会导致链路权重更新出问题。
所以我们需要把除以255后的结果先乘以0.99,然后再加上0.01,这样所有数据就处于0.01到1之间。
'''
scaled_input = image_array / 255.0 * 0.99 + 0.01
import numpy
import matplotlib.pyplot as plt[1]
#open函数里的路径根据数据存储的路径来设定
data_file = open("dataset/mnist_test.csv")
data_list = data_file.readlines()
data_file.close()
print(len(data_list))
print(data_list[0])#把数据依靠','区分,并分别读入
all_values = data_list[0].split(',')
#第一个值对应的是图片的表示的数字,所以我们读取图片数据时要去掉第一个数值
image_array = numpy.asfarray(all_values[1:]).reshape((28, 28))#最外层有10个输出节点
onodes = 10
targets = numpy.zeros(onodes) + 0.01
targets[int(all_values[0])] = 0.99
print(targets)  #targets第8个元素的值是0.99,这表示图片对应的数字是7(数组是从编号0开始的).[2]
'''
根据上述做法,我们就能把输入图片给对应的正确数字建立联系,这种联系就可以用于输入到网络中,进行训练。
由于一张图片总共有28*28 = 784个数值,因此我们需要让网络的输入层具备784个输入节点。
这里需要注意的是,中间层的节点我们选择了100个神经元,这个选择是经验值。
中间层的节点数没有专门的办法去规定,其数量会根据不同的问题而变化。
确定中间层神经元节点数最好的办法是实验,不停的选取各种数量,看看那种数量能使得网络的表现最好。
'''
#初始化网络
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("dataset/mnist_train.csv")
trainning_data_list = training_data_file.readlines()
training_data_file.close()
#把数据依靠','区分,并分别读入
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.01targets[int(all_values[0])] = 0.99n.train(inputs, targets)[3]
'''
最后我们把所有测试图片都输入网络,看看它检测的效果如何
'''
scores = []
for record in test_data_list:all_values = record.split(',')correct_number = int(all_values[0])print("该图片对应的数字为:",correct_number)#预处理数字图片inputs = (numpy.asfarray(all_values[1:])) / 255.0 * 0.99 + 0.01#让网络判断图片对应的数字,推理outputs = n.query(inputs)#找到数值最大的神经元对应的 编号label = numpy.argmax(outputs)  print("output reslut is : ", label)#print("网络认为图片的数字是:", label)if label == correct_number:scores.append(1)else:scores.append(0)
print(scores)#计算图片判断的成功率
scores_array = numpy.asarray(scores)
print("perfermance = ", scores_array.sum() / scores_array.size)[4]
'''
在原来网络训练的基础上再加上一层外循环
但是对于普通电脑而言执行的时间会很长。
epochs 的数值越大,网络被训练的就越精准,但如果超过一个阈值,网络就会引发一个过拟合的问题.
'''
#加入epocs,设定网络的训练循环次数
epochs = 10for 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.01targets[int(all_values[0])] = 0.99n.train(inputs, targets)
import numpy
import scipy.specialclass NeuralNetWork:def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):# 初始化网络,设置输入层,中间层,和输出层节点数self.inodes = inputnodesself.hnodes = hiddennodesself.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.5self.wih = (numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes)))self.who = (numpy.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes)))'''每个节点执行激活函数,得到的结果将作为信号输出到下一层,我们用sigmoid作为激活函数'''self.activation_function = lambda x: scipy.special.expit(x)passdef train(self, inputs_list, targets_list):# 根据输入的训练数据更新节点链路权重'''把inputs_list, targets_list转换成numpy支持的二维矩阵.T表示做矩阵的转置'''inputs = numpy.array(inputs_list, ndmin=2).Ttargets = 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_outputshidden_errors = numpy.dot(self.who.T, output_errors*final_outputs*(1-final_outputs))# 根据误差计算链路权重的更新量,然后把更新加到原来链路权重上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))passdef 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)print(final_outputs)return final_outputs# 初始化网络
'''
由于一张图片总共有28*28 = 784个数值,因此我们需要让网络的输入层具备784个输入节点
'''
input_nodes = 784
hidden_nodes = 200
output_nodes = 10
learning_rate = 0.1
n = NeuralNetWork(input_nodes, hidden_nodes, output_nodes, learning_rate)# 读入训练数据
# open函数里的路径根据数据存储的路径来设定
training_data_file = open("dataset/mnist_train.csv", 'r')
training_data_list = training_data_file.readlines()
training_data_file.close()# 加入epocs,设定网络的训练循环次数
epochs = 5
for e in range(epochs):# 把数据依靠','区分,并分别读入for record in training_data_list:all_values = record.split(',')inputs = (numpy.asfarray(all_values[1:]))/255.0 * 0.99 + 0.01# 设置图片与数值的对应关系targets = numpy.zeros(output_nodes) + 0.01targets[int(all_values[0])] = 0.99n.train(inputs, targets)test_data_file = open("dataset/mnist_test.csv")
test_data_list = test_data_file.readlines()
test_data_file.close()
scores = []
for record in test_data_list:all_values = record.split(',')correct_number = int(all_values[0])print("该图片对应的数字为:", correct_number)# 预处理数字图片inputs = (numpy.asfarray(all_values[1:])) / 255.0 * 0.99 + 0.01# 让网络判断图片对应的数字outputs = n.query(inputs)# 找到数值最大的神经元对应的编号label = numpy.argmax(outputs)print("网络认为图片的数字是:", label)if label == correct_number:scores.append(1)else:scores.append(0)
print(scores)# 计算图片判断的成功率
scores_array = numpy.asarray(scores)
print("perfermance = ", scores_array.sum() / scores_array.size)

相关文章:

从零开始训练神经网络

用Keras实现一个简单神经网络 Keras: Keras是由纯python编写的基于theano/tensorflow的深度学习框架。 Keras是一个高层神经网络API,支持快速实验,能够把你的idea迅速转换为结果,如果有如下需 求,可以优先选择Keras&a…...

连接区块链节点的 JavaScript 库 web3.js

文章目录 前言web3.js 介绍web3.js安装web3.js库模块介绍连接区块链节点向区块链网络发送数据查询区块链网络数据 前言 通过前面的文章我们可以知道基于区块链开发一个DApp,而DApp结合了智能合约和用户界面(客户端),那客户端是如…...

js:scroll平滑滚动页面或元素到顶部或底部的方案汇总

目录 1、CSS的scroll-behavior2、Element.scrollTop3、Element.scroll()/Window.scroll()4、Element.scrollBy()/Window.scrollBy()5、Element.scrollTo()/Window.scrollTo()6、Element.scrollIntoView()7、自定义兼容性方案8、参考文章 准备知识: scrollWidth: 是…...

【Docker】Docker的部署含服务和应用、多租环境、Linux内核的详细介绍

前言 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。 📕作者简介:热…...

C国演义 [第五章]

第五章 子集题目理解步骤树形结构递归函数递归结束的条件单层逻辑 代码 子集II题目理解步骤树形结构递归函数递归结束的条件单层逻辑 代码 子集 力扣链接 给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。…...

Proxy-Reflect使用详解

1 监听对象的操作 2 Proxy类基本使用 3 Proxy常见捕获器 4 Reflect介绍和作用 5 Reflect的基本使用 6 Reflect的receiver Proxy-监听对象属性的操作(ES5) 通过es5的defineProperty来给对象中的某个参数添加修改和获取时的响应式。 单独设置defineProperty是只能一次设置一…...

【Linux后端服务器开发】Shell外壳——命令行解释器

目录 一、Shell外壳概述 二、描述Shell外壳原理的生动例子 三、C语言模拟实现Shell外壳 一、Shell外壳概述 在狭义上 , 我们称Linux操作系统的内核为 Linux 在广义上 , Linux发行版 Linux内核 外壳程序 就比如市面上现在的redhat, centos, ubuntu等等我们耳熟能详的Linux发…...

【无公网IP】在外Windows远程连接MongoDB数据库

文章目录 前言1. 安装数据库2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射2.3 测试随机公网地址远程连接 3. 配置固定TCP端口地址3.1 保留一个固定的公网TCP端口地址3.2 配置固定公网TCP端口地址3.3 测试固定地址公网远程访问 转载自cpolar极点云文章:公网远程…...

mac python3 安装virtualenv

第一步,执行安装virtualenv pip3 install virtualenv 注意:如果出现WARNING: The script virtualenv is installed in ‘/home/local/bin’ which is not on PATH. Consider adding this directory to PATH or, if you prefer to suppress this warning,…...

网络安全(自学笔记)

如果你真的想通过自学的方式入门web安全的话,那建议你看看下面这个学习路线图,具体到每个知识点学多久,怎么学,自学时间共计半年左右,亲测有效(文末有惊喜): 1、Web安全相关概念&am…...

SPSS方差分析

参考文章 导入准备好的数据 选择分析方法 选择参数 选择对比,把组别放入因子框中,把红细胞增加数放进因变量列表 勾选“多项式”,等级取默认“线性” ,继续 接着点击“事后比较”,弹出对话框,勾选“LSD” …...

【Linux】深入理解文件系统

系列文章 收录于【Linux】文件系统 专栏 关于文件描述符与文件重定向的相关内容可以移步 文件描述符与重定向操作。 可以到 浅谈文件原理与操作 了解文件操作的系统接口。 想深入理解文件缓冲区还可以看看文件缓冲区。 目录 系列文章 磁盘 结构介绍 定位数据 抽象管理…...

12.9 专用指令

目录 状态寄存器传送指令 读CPSR 写CPSR 软中断指令 协处理器指令 协处理器数据运算指令 协处理器存储器访问指令 协处理器寄存器传送指令 伪指令 空指令 LDR 指令 伪指令 状态寄存器传送指令 专门用来读写CPSR寄存器的指令 读CPSR MRS R1,CPSR R1 CPSR 写CP…...

Jvm对象回收算法-JVM(九)

上篇文章介绍了jvm运行时候对象进入老年代的场景,以及如何避免频繁fullGC。 Jvm参数设置-JVM(八) 老年代分配担保机制 这个机制的目的是为了提升效率,在minorGC之前,会有三次判断,之后再次minorGC速度会…...

SpringCloud Alibaba微服务分布式架构组件演变

文章目录 1、SpringCloud版本对应1.1 技术选型依据1.2 cloud组件演变: 2、Eureka2.1 Eureka Server : 提供服务注册服务2.2 EurekaClient : 通过注册中心进行访问2.3 Eureka自我保护 3、Eureka、Zookeeper、Consul三个注册中心的异同点3.1 CP…...

【Linux】初步理解操作系统和进程概念

一.认识操作系统 操作系统是一款纯正的 “搞管理” 的文件。 那操作系统为什么要管理文件? “管理” 又是什么? 它是怎么管理的? 为什么? 1.操作系统帮助用户,管理好底层的软硬件资源; 2.为了给用户提供一个…...

TypeScript 中的字面量类型和联合类型特性

字面量类型和联合类型是 TypeScript 中常用的类型特性。 1. 字面量类型: 字面量类型是指具体的值作为类型。例如,字符串字面量类型可以通过给定的字符串字面量来限制变量的取值范围。 let status: "success" | "error"; // status…...

react+jest+enzyme配置及编写前端单元测试UT

文章目录 安装及配置enzyme渲染测试技巧一、常见测试二、触发ant design组件三、使用redux组件四、使用路由的组件五、mock接口网络请求六、mock不需要的子组件 安装及配置 安装相关库: 首先,使用npm或yarn安装所需的库。 npm install --save-dev jest…...

自学网络安全(黑客)

一、为什么选择网络安全? 这几年随着我国《国家网络空间安全战略》《网络安全法》《网络安全等级保护2.0》等一系列政策/法规/标准的持续落地,网络安全行业地位、薪资随之水涨船高。 未来3-5年,是安全行业的黄金发展期,提前踏入…...

【unity小技巧】委托(Delegate)的基础使用和介绍

文章目录 一、前言1. 什么是委托?2. 使用委托的优点 二、举例说明1. 例12. 例2 三、案例四、泛型委托Action和Func1. Action委托2. Func委托 五、参考六、完结 一、前言 1. 什么是委托? 在Unity中,委托(Delegate)是一…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...

C++ 基础特性深度解析

目录 引言 一、命名空间(namespace) C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用(reference)​ C 中的引用​ 与 C 语言的对比​ 四、inline(内联函数…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

🔍 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术,可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势,还能有效评价重大生态工程…...

Ascend NPU上适配Step-Audio模型

1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...

RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程

本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成,用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机: ​onCreate()​​ ​调用时机​:Activity 首次创建时调用。​…...

Java + Spring Boot + Mybatis 实现批量插入

在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法&#xff1a;使用 MyBatis 的 <foreach> 标签和批处理模式&#xff08;ExecutorType.BATCH&#xff09;。 方法一&#xff1a;使用 XML 的 <foreach> 标签&#xff…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...