当前位置: 首页 > 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)是一…...

智能家居开发实战:用RxAndroidBle3实现多设备扫描与信号过滤(附完整Demo)

智能家居BLE开发进阶:RxAndroidBle3多设备扫描与动态过滤实战 在智能家居场景中,蓝牙低功耗(BLE)设备的高效扫描与筛选是构建稳定物联网系统的关键技术。本文将深入探讨如何利用RxAndroidBle3框架实现多设备并发扫描、动态信号过滤…...

AudioSeal效果展示:对抗白噪声、混响、变速变调攻击的鲁棒性案例

AudioSeal效果展示:对抗白噪声、混响、变速变调攻击的鲁棒性案例 1. 音频水印技术新标杆 想象一下,当你听到一段AI生成的语音时,如何确认它的真实来源?这就是AudioSeal要解决的核心问题。作为Meta开源的语音水印系统&#xff0c…...

Wan2.2-I2V-A14B实战:基于LSTM的时序文本生成动态故事视频

Wan2.2-I2V-A14B实战:基于LSTM的时序文本生成动态故事视频 1. 场景与需求分析 在影视制作和互动叙事领域,如何将文字剧本快速转化为视觉预览一直是个耗时费力的过程。传统方法需要美术团队手工绘制分镜或使用基础动画工具,不仅成本高昂&…...

MCU开发 —— GD32篇:SEGGER Embedded Studio 外链编译器实战指南

1. 为什么选择SEGGER Embedded Studio开发GD32 SEGGER Embedded Studio(简称SES)作为一款轻量级跨平台IDE,这几年在嵌入式开发圈子里口碑相当不错。我自己从Keil转过来用SES开发GD32系列MCU已经两年多了,最直观的感受就是编译速度…...

DeepSeek-OCR-2功能测评:多语言支持、复杂背景识别,实测好用

DeepSeek-OCR-2功能测评:多语言支持、复杂背景识别,实测好用 1. 引言:OCR技术的新标杆 在数字化时代,文字识别技术已经成为连接物理世界与数字世界的重要桥梁。DeepSeek-OCR-2作为最新一代的开源OCR模型,凭借其创新的…...

用ESP32和VS1053模块DIY网络收音机:从硬件接线到Arduino代码调试全流程

用ESP32和VS1053打造智能网络收音机:从元器件选型到音频流调试实战 在物联网和智能硬件蓬勃发展的今天,ESP32凭借其出色的无线连接能力和丰富的外设接口,成为DIY音频项目的理想选择。本文将手把手带你完成一个功能完整的网络收音机项目&#…...

面向生产的Chatgpt5.4:系统集成、架构模式与成本优化深度拆解

对于计划将顶级AI能力深度集成至自身产品与工作流的团队而言,理解Gemini 3.1 Pro的系统级特性、集成模式与全生命周期成本至关重要。国内开发者可通过RskAi(www.rsk.cn)等聚合平台,以零成本、国内直访的方式完成前期技术验证与原型…...

BetterGI完整指南:原神自动化助手的功能解析与使用教程

BetterGI完整指南:原神自动化助手的功能解析与使用教程 【免费下载链接】better-genshin-impact 🍨BetterGI 更好的原神 - 自动拾取 | 自动剧情 | 全自动钓鱼(AI) | 全自动七圣召唤 | 自动伐木 | 自动派遣 | 一键强化 - UI Automation Testing Tools Fo…...

基于Session管理的在线视频学习平台防作弊策略

1. Session管理在在线学习平台中的核心作用 在线视频学习平台最头疼的问题之一,就是如何防止用户通过多设备同时登录来刷学习进度。想象一下,如果用户同时在手机、平板和电脑上登录同一个账号,三倍速刷完课程,这对其他认真学习的用…...

Python AOT编译面试通关手册(仅限2026 Q1–Q3内推通道开放期|含6家头部公司真实压轴题及参考实现)

第一章:Python AOT编译技术演进与2026面试全景图Python 长期以来以解释执行和 JIT(如 PyPy)为主流,但面向云原生、边缘计算与安全敏感场景,AOT(Ahead-of-Time)编译正加速进入主流视野。从早期的…...