神经网络例程-使用(3-1)结构的神经网络实现与、或、异或三种逻辑运算

以下代码来自Deep Learning for Computer Vision with Python第十章。

本例程需要在同一文件内新建四个文件。分别是1、perceptron.py;2、perceptron_or.py;3、perceptron_and.py;4、perceptron_xor.py。

1、perceptron.py

# import the necessary packages
import numpy as np

class Perceptron:
	def __init__(self, N, alpha=0.1):
		# initialize the weight matrix and store the learning rate
		self.W = np.random.randn(N + 1) / np.sqrt(N)
		self.alpha = alpha
		
	def step(self, x):
		# apply the step function
		return 1 if x > 0 else 0
		
	def fit(self, X, y, epochs=10):
		# insert a column of 1's as the last entry in the feature
		# matrix -- this little trick allows us to treat the bias
		# as a trainable parameter within the weight matrix
		X = np.c_[X, np.ones((X.shape[0]))]
		
		# loop over the desired number of epochs
		for epoch in np.arange(0, epochs):
			# loop over each individual data point
			for (x, target) in zip(X, y):
				# take the dot product between the input features
				# and the weight matrix, then pass this value
				# through the step function to obtain the prediction
				p = self.step(np.dot(x, self.W))

				#print("[training] self.W={}, x={}, target={}".format(self.W, x, target))
				
				# only perform a weight update if our prediction
				# does not match the target
				if p != target:
					# determine the error
					error = p - target

					# update the weight matrix
					self.W += -self.alpha * error * x

	def predict(self, X, addBias=True):
		# ensure our input is a matrix
		X = np.atleast_2d(X)

		# check to see if the bias column should be added
		if addBias:
			# insert a column of 1's as the last entry in the feature
			# matrix (bias)
			X = np.c_[X, np.ones((X.shape[0]))]

		# take the dot product between the input features and the
		# weight matrix, then pass the value through the step
		# function
		return self.step(np.dot(X, self.W))
		

分析:Perception类是一个(3-1)结构的神经网络,(3-1)代表有输入层有3个神经元(其中两个神经元用于处理输入参数x1和x2,另外一个神经元输入固定为1),输出层有1个神经元。示意图见下图。

神经网络权重文件除了权重(w1和w2),还加上了偏置(b)。本身输入参数只有两个,对应的权值是w1和w2,输入层神经元为3的目的是把偏置b也加入权重矩阵中。当训练权重矩阵时,偏置b也得以更新。输出参数的表达式是y=step(x1*w1+x2*w2+b)。

神经元的激活函数是Step函数。Step函数包含一个输入参数和一个输出参数。当输入小于0,则输出为0;当输入大于0,则输出1。

fit函数用于训练,使用的是随机梯度下降法。predict函数作用是测试样品,把目标样品经过本神经网络,获得预测结果。

2、perceptron_or.py

# import the necessary packages
from perceptron import Perceptron
import numpy as np

# construct the OR dataset
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [1]])

# define our perceptron and train it
print("[INFO] training perceptron...")
p = Perceptron(X.shape[1], alpha=0.1)
p.fit(X, y, epochs=20)

# now that our perceptron is trained we can evaluate it
print("[INFO] testing perceptron...")

# now that our network is trained, loop over the data points
for (x, target) in zip(X, y):
	# make a prediction on the data point and display the result
	# to our console
	pred = p.predict(x)
	print("[INFO] data={}, ground-truth={}, pred={}".format(
		x, target[0], pred))
		

在或运算中,两个输入参数和一个输出参数的关系见下表。

逻辑运算-或
输入参数1:x1输入参数2:x2输出参数:y
000
011
101
111

Perceptron函数用于新建一个2层神经网络。第一个输入参数X.shape[1]是X中每个样品的参数个数。alpha是梯度下降、更新权值的速度。越接近1,速度越快,但是越大越容易错过局部最大值。

fit函数第一个参数是样品的输入参数矩阵,第二个参数是样品的输入参数的输出矩阵(真实值),第三个参数是迭代次数。data是样品的输入参数,ground-truth表示真实值,pred是预测结果。

用python运行perceptron_or.py,可得到以下结果:

============= RESTART: E:\FENG\workspace_python\perceptron_or.py =============
[INFO] training perceptron...
[INFO] testing perceptron...
[INFO] data=[0 0], ground-truth=0, pred=0
[INFO] data=[0 1], ground-truth=1, pred=1
[INFO] data=[1 0], ground-truth=1, pred=1
[INFO] data=[1 1], ground-truth=1, pred=1

3、perceptron_and.py

# import the necessary packages
from perceptron import Perceptron
import numpy as np

# construct the OR dataset
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [0], [0], [1]])

# define our perceptron and train it
print("[INFO] training perceptron...")
p = Perceptron(X.shape[1], alpha=0.1)
p.fit(X, y, epochs=20)

# now that our perceptron is trained we can evaluate it
print("[INFO] testing perceptron...")

# now that our network is trained, loop over the data points
for (x, target) in zip(X, y):
	# make a prediction on the data point and display the result
	# to our console
	pred = p.predict(x)
	print("[INFO] data={}, ground-truth={}, pred={}".format(
		x, target[0], pred))
		

这个文件和上面那份文件差别不大,因此不分析了。

4、perceptron_xor.py

# import the necessary packages
from perceptron import Perceptron
import numpy as np

# construct the OR dataset
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])

# define our perceptron and train it
print("[INFO] training perceptron...")
p = Perceptron(X.shape[1], alpha=0.1)
p.fit(X, y, epochs=20)

# now that our perceptron is trained we can evaluate it
print("[INFO] testing perceptron...")

# now that our network is trained, loop over the data points
for (x, target) in zip(X, y):
	# make a prediction on the data point and display the result
	# to our console
	pred = p.predict(x)
	print("[INFO] data={}, ground-truth={}, pred={}".format(
		x, target[0], pred))
		

结果如下:

============ RESTART: E:\FENG\workspace_python\perceptron_xor.py ============
[INFO] training perceptron...
[INFO] testing perceptron...
[INFO] data=[0 0], ground-truth=0, pred=1
[INFO] data=[0 1], ground-truth=1, pred=1
[INFO] data=[1 0], ground-truth=1, pred=0
[INFO] data=[1 1], ground-truth=0, pred=0

可见,异或的预测结果并不准确。主要因为,只具有2层神经元、而不具备隐含层的神经网络并无法非线性的对样品分类。

上图说明的是,与和或样本的空间分布,因为可以用一条直线把输出0和输出1的样本分类,因此比较简单。经过实践发现,使用2层神经网络的分类器也能实现预期效果。但是,异或的样本逻辑比较复杂。

为了正确分类异或样本,必须改变神经网络结构,进一步增加隐含层,尝试重新训练以及测试。

  • 4
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是一个基本的使用Emgu CV实现图像分类的程,包括数据的预处理、神经网络的构建、训练和测试: ```csharp using Emgu.CV; using Emgu.CV.ML; using Emgu.CV.Structure; using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace ImageClassification { class Program { static void Main(string[] args) { // 设置数据集的路径 string dataPath = @"C:\data\images"; // 读取数据集 List<Image<Gray, byte>> images = LoadImages(dataPath); // 划分训练集和测试集 List<Image<Gray, byte>> trainImages = images.Take(500).ToList(); List<Image<Gray, byte>> testImages = images.Skip(500).ToList(); // 准备训练和测试数据 Matrix<float> trainData = PrepareData(trainImages); Matrix<float> trainLabels = PrepareLabels(trainImages); Matrix<float> testData = PrepareData(testImages); Matrix<float> testLabels = PrepareLabels(testImages); // 创建神经网络 ANN_MLP neuralNetwork = new ANN_MLP(); neuralNetwork.SetLayerSizes(new int[] { trainData.Rows, 100, 50, 10 }); neuralNetwork.TermCriteria = new MCvTermCriteria(100, 0.01); neuralNetwork.SetActivationFunction(ANN_MLP.AnnMlpActivationFunction.SigmoidSym, 0, 0); neuralNetwork.SetTrainMethod(ANN_MLP.AnnMlpTrainMethod.Backprop, 0.1, 0.1); // 训练神经网络 neuralNetwork.Train(trainData, trainLabels); // 测试神经网络 float[] expectedLabels = new float[testLabels.Rows]; float[] predictedLabels = new float[testLabels.Rows]; for (int i = 0; i < testLabels.Rows; i++) { float[] testDataRow = testData.GetRow(i); float[] testLabelRow = testLabels.GetRow(i); neuralNetwork.Predict(testDataRow, predictedLabels); expectedLabels[i] = Array.IndexOf(testLabelRow, 1); } int correctPredictions = expectedLabels.Zip(predictedLabels, (e, p) => e == p ? 1 : 0).Sum(); float accuracy = (float)correctPredictions / testLabels.Rows; Console.WriteLine($"Test accuracy: {accuracy}"); } // 加载图像 static List<Image<Gray, byte>> LoadImages(string dataPath) { List<Image<Gray, byte>> images = new List<Image<Gray, byte>>(); foreach (string imagePath in Directory.GetFiles(dataPath)) { Image<Gray, byte> image = new Image<Gray, byte>(imagePath); images.Add(image); } return images; } // 准备数据 static Matrix<float> PrepareData(List<Image<Gray, byte>> images) { int numImages = images.Count; int numPixels = images[0].Width * images[0].Height; Matrix<float> data = new Matrix<float>(numImages, numPixels); for (int i = 0; i < numImages; i++) { Image<Gray, byte> image = images[i]; float[] pixels = image.Data.SelectMany(row => row).Select(x => (float)x / 255f).ToArray(); data.SetRow(i, pixels); } return data; } // 准备标签 static Matrix<float> PrepareLabels(List<Image<Gray, byte>> images) { int numImages = images.Count; int numClasses = 10; // 假设有10个类别 Matrix<float> labels = new Matrix<float>(numImages, numClasses); for (int i = 0; i < numImages; i++) { int label = i % numClasses; labels[i, label] = 1f; } return labels; } } } ``` 这个实现了一个简单的多层感知器神经网络,用于对图像进行分类。它假设数据集中有10个类别,每个类别有50张图像。它将前500张图像用于训练,后50张用于测试。在训练神经网络时,它使用反向传播算法和Sigmoid激活函数,并设置了一些超参数。在测试时,它计算了分类的准确度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值