分类 深度学习 下的文章

夫道未始有封,言未始有常,为是而有畛也。

作为《深度学习入门》的阅读笔记,本文简略概述感知机,并辅以python实现

Python基础

再简单的描述离不开基本的语言基础,确保了解《蜻蜓点水-python》中的内容在进行下去

逻辑运算和感知机

如上所述,python中有逻辑运算,电路中也有逻辑运算,并以“门”的形式呈现,有电流则为1(True),无电流则为0(True)。

如下图所示,三种门的符号,真值表就不再赘述,可以用python快速验证
image-20251009214626196.png

感知机的历史1957提出,是神经网络的起源的算法之一。

感知机接受多个信号,并输出一个信号。

感知机实现

先说实现的思路,上述三种逻辑运算都可以用同一种逻辑表达,区别只在于特定参数的不同

image-20251009215857997.png

b称为偏置,w称为权重,二者控制了函数的不同逻辑表示

下面直接给出代码实现:

  • 初始化函数设定了权重和偏置
  • forward函数在深度学习中代表正向传播,这里借用作为感知机的处理函数
  • 逻辑如公式,但将等号给了1
class Perceptron:
    def __init__(self, w=np.array([0,0]),delta=-1.):
        self.w=w
        self.delta = delta
    def forward(self,x):
        tmp=self.w*x
        if np.sum(tmp) + self.delta < 0:
            return 0
        else:
            return 1
andclass = Perceptron(w=np.array([0.5,0.5]))
print(andclass.forward(np.array([0,0])))
print(andclass.forward(np.array([1,0])))
print(andclass.forward(np.array([0,1])))
print(andclass.forward(np.array([1,1])))
# 0
# 0
# 0
# 1
orclass = Perceptron(w=np.array([1,1]))
print(orclass.forward(np.array([0,0])))
print(orclass.forward(np.array([1,0])))
print(orclass.forward(np.array([0,1])))
print(orclass.forward(np.array([1,1])))

# 0
# 1
# 1
# 1
nandclass = Perceptron(w=np.array([-0.5,-0.5]),delta=0.9)
print(nandclass.forward(np.array([0,0])))
print(nandclass.forward(np.array([1,0])))
print(nandclass.forward(np.array([0,1])))
print(nandclass.forward(np.array([1,1])))

# 1
# 1
# 1
# 0

目前感知机的局限

可以对当前感知机的输入和输出作图,可得:
image-20251009220709154.png

总之,有办法做一条直线将0和1的结果划分开,能这么表示的称为线性感知机

但是这样的感知机无法表示XOR操作,也就是异或操作:

image-20251009220911874.png

XOR感知机的实现

该问题由1969年被提出,直到1986年被解决,这段时间人工智能的发展是停滞的。

解决的方法就是使用多层感知机,即单独的“门”无法解决的问题,就用多个连接一起解决,直接给方法:
image-20251009221438817.png

用代码表示就是:

def XOR(x1, x2):
    s1 = NAND(x1, x2)
    s2 = OR(x1, x2)
    y = AND(s1, s2)
    return y

进一步的实现:

#def XOR(x1, x2):
#    s1 = NAND(x1, x2)
#    s2 = OR(x1, x2)
#    y = AND(s1, s2)
#    return y
class XOR:
    def __init__(self):
        self.nandclass = Perceptron(w=np.array([-0.5,-0.5]),delta=0.9)
        self.orclass = Perceptron(w=np.array([1,1]))
        self.andclass = Perceptron(w=np.array([0.5, 0.5]))
    def forward(self,x):
        s1 = self.nandclass.forward(x)
        s2 = self.orclass.forward(x)
        tmp = self.andclass.forward(np.array([s1,s2]))
        return tmp

print("XOR: ")
print(XOR().forward(np.array([0,0])))
print(XOR().forward(np.array([1,0])))
print(XOR().forward(np.array([0,1])))
print(XOR().forward(np.array([1,1])))

#XOR: 
#0
#1
#1
#0

其他问题

多层感知机的层数

按权重算,2层,因为有两套权重参数

按节点(神经元)算,3层,从输入,到中间结果,到输出,有三个阶段

多层感知机的进一步

感知机通过叠加层能够进行非线性的表示,理论上还可以表示计算机进行的处理

多层感知机可以认为是一种神经网络

道在屎溺。作为《深度学习入门》的阅读笔记,本文简略概述python

算数计算

print(1 - 2)
print(4 * 5)
print(7 / 5)
print(3 ** 2) # 乘方
-1
20
1.4
9

数据类型和Type函数

type(10)
int



type(2.718)
float



type("hello")
str



type(True)
bool


变量

x = 100
y = 3.14
print(x * y)
type(x * y)
# 是注释标识
314.0

float


列表

a = [1,2,3,4,5]
print(a)
len(a)
[1, 2, 3, 4, 5]

5



print(a[4])
a[4]=99
print(a)
5
[1, 2, 3, 4, 99]


# 切片
a[0:2] # 获取索引为0到2(不包括2!)的元素
[1, 2]



a[1:]  # 获取从索引为1的元素到最后一个元
[2, 3, 4, 99]



a[:3]  # 获取从第一个元素到索引为3(不包括3!)的元素
[1, 2, 3]



a[:-1] # 获取从第一个元素到最后一个元素的前一个元素之间的元素
[1, 2, 3, 4]



a[:-2] # 获取从第一个元素到最后一个元素的前二个元素之间的元素
[1, 2, 3]


字典

me = {'height':180} # 生成字典
print(me)
{'height': 180}


me['height']=70
print(me['height'])
70

布尔型

hungry = True
sleepy = False
type(hungry)
bool



not hungry
False



hungry and sleepy
False



hungry or sleepy
True


if语句

if hungry:
    print('hungry')
elif sleepy:
    print('sleepy')
else:
    print('not hungry')
hungry

for 语句

for i in [1,2,3]:
    print(i)
1
2
3

函数

def hello(object):
    print("Hello " + object + "!")
hello("cat!")
Hello cat!!

class Man:
    def __init__(self, name):
        self.name = name
        print("Initialized!")
    def hello(self):
        print("Hello " + self.name + "!")
    def goodbye(self):
        print("Good-bye " + self.name + "!")

m = Man("David")
m.hello()
m.goodbye()
Initialized!
Hello David!
Good-bye David!

Numpy 速成

import numpy as np

x = np.array([1.,2.,3.])
print(x)
type(x)
y = np.array([2.0, 4.0, 6.0])
[1. 2. 3.]

以下是对应元素的运算,如果元素个数不同,程序就会报错,所以元素个数保持一致非常重要

print(x+y)
print(x-y)
print(x/y)
print(x*y)
[3. 6. 9.]
[-1. -2. -3.]
[0.5 0.5 0.5]
[ 2.  8. 18.]

NumPy数组不仅可以进行element-wise运算,也可以和单一的数值(标量)组合起来进行运算

x/2.0
array([0.5, 1. , 1.5])


Numpy的N维数组

A = np.array([[1, 2], [3, 4]])
B = np.array([[3, 0],[0, 6]])
print(A)
[[1 2]
 [3 4]]


A.shape
(2, 2)



A.dtype
dtype('int32')



print(A+B)
[[ 4  2]
 [ 3 10]]


print(A*B)
[[ 3  0]
 [ 0 24]]


print(A*10)
[[10 20]
 [30 40]]

广播

A = np.array([[1, 2], [3, 4]])
B = np.array([10, 20])
A * B
array([[10, 40],
       [30, 80]])


访问元素

X = np.array([[51, 55], [14, 19], [0, 4]])
X[0][1]
55



X[0]
array([51, 55])



for row in X:
    print(row)
[51 55]
[14 19]
[0 4]


X = X.flatten()
print(X)
[51 55 14 19  0  4]

还有一些特殊的访问方法:

X[np.array([0, 2, 4])]
array([51, 14,  0])



X > 15
array([ True,  True, False,  True, False, False])



X[X>15]
array([51, 55, 19])


Matplolib 速成

import matplotlib.pyplot as plt
 # 生成数据
x = np.arange(0, 6, 0.1) # 以0.1为单位,生成0到6的数据
y1 = np.sin(x)
y2 = np.cos(x)
# 绘制图形
plt.plot(x, y1)
plt.show()

test_python_59_0.png

plt.plot(x, y1, label="sin")
plt.plot(x, y2, linestyle = "--", label="cos") # 用虚线绘制
plt.xlabel("x") # x轴标签
plt.ylabel("y") # y轴标签
plt.title('sin & cos') # 标题
plt.legend() #图例
plt.show()


test_python_60_0.png

from matplotlib.image import imread
img = imread('../dataset/lena.png') # 读入图像(设定合适的路径!)
plt.imshow(img)
plt.show()


test_python_61_0.png