9、线性代数:人工智能数据基础

1.线性代数基础概念:标量、向量、矩阵、张量

标量

定义:

标量是只有大小没有方向的量。在数学中,它通常是一个实数或复数。

通俗:

想象你有5个苹果。这个数字 “5” 就是一个标量。它只告诉你有多少苹果,但不告诉你这些苹果放在哪里。

向量

定义:

向量是具有大小和方向的量。在数学中,它通常表示为一个有序的数字列表,如二维或三维空间中的点。

通俗:

想象你在一个大房间里,你想告诉你的朋友一个宝藏的位置。你可以说:“从门口开始,走5步向前,然后走3步向右” 。这个 “5步向前和3步向右” 就像一个向量,它有方向和距离。

矩阵

定义:

矩阵是一个二维数组,其中的每个元素都是一个标量。它可以表示线性变换。

通俗:

想象你有一个秘密地图,上面有很多宝藏的位置。为了整齐的记录所有的位置,你决定用一个网格或表格来写下所有的 “向前和向右” 的步数。这个表格就像一个矩阵,它帮助你整齐地记录信息。

张量

定义:

张量是一个可以在多个方向上有分量的数学对象。标量是零阶张量,向量是一阶张量,矩阵是二阶张量。更高阶的张量可以看做是多维数组。

通俗:

想象你不仅在一个房间里找宝藏,而且在一个大楼里。这是,你不仅要告诉你的朋友向前多少步、向右多少步,还要告诉他上或下走多少楼梯。如果你用一个更大的表格来记录这些信息,其中包括向前、向右和上下的步数,这就像一个张量。张量就是一个更高级的表格,可以记录更多的信息。

2.向量(矩阵)的范数与单位向量

 向量的范数

定义

向量的范数是一个函数,它将向量映射到一个非负值。直观地说,范数表示向量的“长度”或“大小”。对于向量 (v),其范数通常表示为 (∣∣v∣∣)。

通俗

想象你在一个城市的地图上,从你家走到一个公园。这条路线就像一个向量。范数就是你需要走的距离,也就是从家到公园的实际步数。

矩阵的范数

单位向量

定义

单位向量是长度(或范数)为1的向量。对于任何非零向量 (v),其对应的单位向量可以通过将 (v)除以其L2范数得到:

通俗解释

假设你不关心走多远,只想知道公园的方向。你拿出一个指南针,它指向公园的方向,但不告诉你有多远。这个指南针的指向就像一个单位向量。

3.案例实战:创建向量、矩阵、张量

import numpy as np

# 创建向量(一维)
vector = np.array([1, 2, 3, 4, 5])
vector_norm = np.linalg.norm(vector)  # 矩阵或向量的范数
print(f"Vector:\n{vector}")
print(f"Vector L2 Norm: {vector_norm}")

# 创建矩阵(二维)
matrix = np.array([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
])
matrix_norm = np.linalg.norm(matrix)
print(f"Matrix:\n{matrix}")
print(f"Matrix L2 Norm: {matrix_norm}")

# 创建张量(三维)
tensor = np.array([
    [[1, 2], [3, 4]],
    [[5, 6], [7, 8]],
    [[9, 10], [11, 12]]
])
tensor_norm = np.linalg.norm(tensor)
print(f"Tensor:\n{tensor}")
print(f"Tensor L2 Norm: {tensor_norm}")

4.案例实战:将Numpy矩阵保存成本地图像

import numpy as np
import cv2

# 创建一个大小为224X224的二维矩阵,值为0~255之间
two_d_matrix = np.random.randint(0, 256, (224, 224), dtype=np.uint8)

# 创建一个大小为3X224X224的三维矩阵,值为0~255之间
three_d_matrix = np.random.randint(0, 256, (3, 224, 224), dtype=np.uint8)

# 在 OpenCv 中,图像的通道顺序为 高 X 宽 X 通道数
three_d_matrix_transposed = three_d_matrix.transpose(1, 2, 0)

# 将画面显示出来
cv2.imshow("two_d_matrix", two_d_matrix)
cv2.imshow("three_d_matrix", three_d_matrix_transposed)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 使用 OpenCv 将图片保存到本地
cv2.imwrite("two_d_matrix.jpg", two_d_matrix)
cv2.imwrite("three_d_matrix.jpg", three_d_matrix_transposed)

5.案例实战:图像增强(调整对比度)

矩阵基础运算

矩阵的加法

标量与矩阵的乘法

案例实践

import numpy as np

# 定义矩阵A和B
matrix_a = np.array([
    [1, 2],
    [3, 4]
])

matrix_b = np.array([
    [5, 6],
    [7, 8]
])

# 定义标量C
scalar_c = 3

# 标量与矩阵的乘法
scalar_mult_matrix = matrix_a * scalar_c

# 矩阵的加法
matrix_add = matrix_a + matrix_b

print(scalar_mult_matrix)
print(matrix_add)

图像增强(调整对比度)

import numpy as np
import cv2

# 读取图像
image = cv2.imread("robot(1).jpg")

# 增加对比度
# 为了避免溢出,使用cv2.convertScaleAbs而不是直接乘法
increased_contrast = cv2.convertScaleAbs(image, alpha=1.5)  # 表示对 image 每个像素值在原来基础上乘1.5

# 减少对比度
decreased_contrast = cv2.convertScaleAbs(image, alpha=0.5)

# 将图片进行横向拼接
combined_image = cv2.hconcat([image, increased_contrast, decreased_contrast])

# 显示图片
cv2.imshow("Original - Increased Contrast - Decreased Contrast", combined_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 图像增强(调整亮度)

 

import cv2
import numpy as np

# 读取图片
image = cv2.imread('robot(1).jpg')  # 替换为你的图片路径

# 增加亮度
# 为了避免溢出,使用cv2.add而不是直接加法
brighter_image = cv2.add(image, np.array([50.0]))  # 增加亮度

# 减少亮度
# 同样,使用cv2.subtract避免溢出
darker_image = cv2.subtract(image, np.array([50.0]))  # 减少亮度

# 将原图、增亮后的图和减暗后的图横向拼接
combined_image = cv2.hconcat([image, brighter_image, darker_image])

# 显示图片
cv2.imshow('Original - Brighter - Darker', combined_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

6.Python实现解方程组

矩阵的逆

对于一个方阵(即行数和列数相同的矩阵)A,如果存在另一个矩阵 B 使得 A 和 B 相乘的结果是单位矩阵(对角线上都是 1,其他位置都是 0 的矩阵),那么 B 就是 A 的逆矩阵,通常表示为 

不是所有的矩阵都有逆。只有当矩阵的行列式不为 0 时,矩阵才有逆。

行列式

行列式是一个与方阵相关的标量值。对于 2 X 2 的矩阵,其行列式计算相对简单。但对于更大的矩阵,计算会更复杂。

行列式有很多重要的性质和应用,其中之一是:一个矩阵是可逆的当且仅当起行列式不为0。

行列式常用符号|A|det(A)

矩阵的秩

矩阵的秩描述了矩阵的 “大小” 或 “维度”。更具体地说,它是矩阵中线性对立的行或列的最大数量。

例如,如果一个矩阵的所有行都是其他行的倍数,那么这个矩阵的秩是 1,因为只有一个线性独立的行。

矩阵的秩对于解决线性方程组很有用,因为它可以帮助我们判断方程组是否有解,以及解的数量。

解方程

使用代码解方程

import numpy as np

# 创建系数矩阵
A = np.array([
    [1, 2, 3],
    [1, 6, 7],
    [1, 10, 6]
])

# 创建常数向量
B = np.array([5, 9, 8])

# 解方程
x = np.linalg.solve(A, B)  # 求解线性矩阵方程或线性标量方程组。

# 打印结果
print(f"解:{x}")

7.特征向量与特征值实操

特征值

定义:

与特征向量相对应的标量 λ 称为特征值。它表示在特定的特征向量方向上,变换的缩放比例。

想象一个拉伸机,你放入一根箭头,拉伸机的作用下,这根箭头可能会被拉长、缩短或者保持原长,但方向不变。这个 “拉伸” 或者 “缩短” 的倍数,就是特征值。特征值反映了这个变换增强或减弱了向量的程度。

特征向量

定义:

如果一个非零向量 v 在一个线性变换下的效果仅仅是被伸缩(缩放或拉伸),而方向不变,那么这个向量被称为特征向量。

那根被拉伸后方向不变的箭头,就是特征向量。它是一个特殊的向量,它在矩阵变换下只是被伸缩,但不改变其方向。可以指明变换的主要方向。

 特征值和特征向量求解

import numpy as np

# 定义矩阵A
A = np.array([
    [4, 1],
    [2, 3]
])

# 使用 numpy 求特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(A)

print(f"特征值:{eigenvalues}")
print(f"特征向量:\n{eigenvectors}")

8.案例实战:图像的SVD分解

在数学上,对于一幅图像的SVD分解,我们可以将其分解为三个部分:

  1. U 矩阵:这个矩阵包含了所谓的“左奇异向量”,可以想象成是一组基础的图像模式。
  2. Σ(Sigma)矩阵:这个对角矩阵包含了所谓的“奇异值”,这些值表明了每个图像模式的重要性或权重。较大的奇异值对应于图像中更重要的特征。
  3. V 矩阵:这个矩阵包含了“右奇异向量”,它与U矩阵类似,但从不同的角度描述了图像的特征。

通过这种分解,一幅图像就被转化成了一系列的模式和对应的权重。你可以通过仅仅结合前几个最重要的模式(即权重最大的那些)来近似重构原始图像。这种方法在图像压缩和降噪中非常有用,因为它允许我们用较少的数据来描述一幅图像,同时保留其关键特征。

import cv2
import numpy as np

# 读取图片
image = cv2.imread("robot(1).jpg", 0)  # 自动图片转变为灰度图像

# 对图像进行 SVD 分解
U, S, V = np.linalg.svd(image.astype(np.float64), full_matrices=False)
# image.astype(np.float64) 将图片格式转换为浮点型

# 定义要保留的奇异值数量
k = 50
s_k = np.diag(S[:k])  # 提取对角线或构造对角线数组。

# 重构图像
compressed_image = np.dot(U[:, :k], np.dot(s_k, V[:k, :]))  # dot 两个阵列的点积。
compressed_image = np.clip(compressed_image, 0, 255).astype(np.uint8)  # clip 剪切(限制)数组中的值。

# 显示图像
cv2.imshow("Original Image", image)
cv2.imshow("Compress Image", compressed_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值