Python 机器学习求解 PDE 学习项目 基础知识(1)

认识 Numpy 数组

Numpy在PDE(偏微分方程)深度学习和图像处理中都有着广泛的应用。以下是对这两方面应用的简述:

Numpy在PDE深度学习中的应用

  • 数据表示与预处理:
    在PDE深度学习中,数据通常以多维数组的形式存在,如网格点上的物理量(如温度、压力等)。Numpy提供了高效的多维数组对象,可以方便地表示这些数据。
    利用Numpy的数组操作功能,可以对数据进行预处理,如归一化、标准化等,以便于深度学习模型的训练。
  • 数值计算:
    PDE的求解往往涉及到复杂的数值计算,如有限差分法、有限元法等。Numpy提供了丰富的数学函数和线性代数工具,可以方便地实现这些数值计算方法。
    例如,可以使用Numpy的dot函数进行矩阵乘法,以实现线性方程组的求解;使用linalg.eig函数计算矩阵的特征值和特征向量,以进行稳定性分析等。
  • 模型训练与评估:
    在深度学习模型的训练过程中,需要不断地计算损失函数并更新模型参数。Numpy可以高效地计算这些损失函数和梯度,并用于模型的优化。
    在模型评估阶段,Numpy可以用于计算预测结果与实际数据之间的误差,以评估模型的性能。

Numpy在图像处理中的应用

  • 图像数据表示:
    图像通常以二维或三维数组的形式表示,其中二维数组表示灰度图像,三维数组(高度×宽度×通道数)表示彩色图像。Numpy的多维数组对象非常适合用于表示图像数据。
  • 图像预处理:
    在图像处理任务中,经常需要对图像进行预处理,如裁剪、缩放、旋转、滤波等。Numpy的数组操作功能可以方便地实现这些预处理操作。
    例如,可以使用Numpy的切片功能来裁剪图像;使用广播机制来实现图像的缩放和旋转;使用卷积操作来实现图像的滤波等。
  • 特征提取与变换:
    在深度学习中,特征提取是图像处理任务中的一个重要环节。Numpy可以用于实现各种特征提取和变换方法,如直方图均衡化、边缘检测、霍夫变换等。
    这些方法通常涉及到复杂的数学运算和图像处理技术,Numpy的线性代数和数学函数库为这些运算提供了强大的支持。

代码示例

下面这个脚本包含了NumPy的多种基本操作,如数组创建、变换、数学运算、线性代数等,帮助读者认识 Numpy 基本操作。

import numpy as np  
  
# 创建数组  
arr_1d = np.array([1, 2, 3, 4, 5])  
arr_2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])  
arr_3d = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])  

print("Original 2D Array:\n", arr_2d)  

# 数组变换  
# 转置  
arr_2d_t = arr_2d.T  
# 扁平化  
arr_flat = arr_2d.flatten()  
# 重塑  
arr_reshaped = arr_flat.reshape((3, 3))  
# 切片  
slice_arr = arr_2d[1:3, 1:3]  
# 索引  
element = arr_2d[1, 1]  
# 广播  
arr_broadcast = arr_1d + 10  # 每一个元素都加10  
# 数组拼接  
arr_stacked_v = np.vstack((arr_2d, arr_2d + 10))  
arr_stacked_h = np.hstack((arr_2d, arr_2d + 10))  
# 数组条件筛选  
filtered_arr = arr_2d[arr_2d > 5]  
# 数组排序  
sorted_arr = np.sort(arr_2d, axis=0)  
# 线性代数  
# 点积  
dot_product = np.dot(arr_2d, arr_2d.T)  
# 特征值和特征向量  
eigenvalues, eigenvectors = np.linalg.eig(dot_product)  
# 矩阵逆  
if np.linalg.det(arr_2d) != 0:  
    inv_arr = np.linalg.inv(arr_2d)  
# 随机数组  
rand_arr = np.random.rand(3, 4)  
# 统计函数  
mean_val = np.mean(arr_2d)  
std_dev = np.std(arr_2d)  
# 数组条件赋值  
arr_2d[arr_2d > 5] = 0  
# 数组迭代  
for row in arr_2d:  
    print(row)  
# 更多操作可以继续添加...  
  
# 打印一些结果  

print("Transposed 2D Array:\n", arr_2d_t)  
print("Flattened Array:\n", arr_flat)  
print("Reshaped Array:\n", arr_reshaped)  
print("Sliced Array:\n", slice_arr)  
print("Element at [1, 1]:", element)  
print("Broadcasted Array:\n", arr_broadcast)  
print("Vertically Stacked Array:\n", arr_stacked_v)  
print("Horizontally Stacked Array:\n", arr_stacked_h)  
print("Filtered Array:\n", filtered_arr)  
print("Sorted Array:\n", sorted_arr)  
print("Dot Product:\n", dot_product)  
print("Eigenvalues:\n", eigenvalues)  
print("Eigenvectors:\n", eigenvectors)  
if np.linalg.det(arr_2d) != 0:  
    print("Inverse of Array:\n", inv_arr)  
print("Random Array:\n", rand_arr)  
print("Mean Value:", mean_val)  
print("Standard Deviation:", std_dev)  
print("Modified Array:\n", arr_2d)

Class 的使用

在PDE(偏微分方程)深度学习中,Class(类)的使用主要体现在通过编程和软件开发来构建和训练深度神经网络模型,这些模型能够用于求解或近似求解PDE。Class作为面向对象编程(OOP)中的基本概念,用于定义对象的属性和方法,为PDE深度学习的实现提供了强大的抽象和封装能力。以下是Class在PDE深度学习中可能的应用的几个方面:

  1. 定义神经网络结构
  • 自定义网络层:通过创建新的Class来定义特定类型的神经网络层(如卷积层、池化层、全连接层等),这些层可以针对PDE求解的特点进行优化。
  • 网络架构:利用Class定义整个神经网络的架构,包括层的顺序、连接方式和激活函数等,以便能够高效地处理PDE相关的输入和输出。
  1. 实现损失函数和优化算法
  • 损失函数:PDE深度学习中,通常需要定义与PDE解相关的损失函数来评估模型的性能。通过Class,可以灵活地定义这些损失函数,包括基于PDE残差、边界条件或能量泛函的损失等。
  • 优化算法:利用Class实现优化算法(如梯度下降、Adam等),这些算法用于调整神经网络的参数以最小化损失函数。
  1. 数据预处理和后处理
  • 数据加载和预处理:通过Class定义数据加载和预处理流程,包括数据归一化、边界条件处理、网格划分等,以确保数据适合用于训练PDE深度学习模型。
  • 结果后处理:在模型训练完成后,可以使用Class来执行结果的后处理,如可视化、误差分析、性能评估等。
  1. 迁移学习和模型重用
  • 迁移学习:在某些情况下,可以将在一个PDE问题上训练好的模型迁移到另一个相似的PDE问题上。通过Class,可以方便地保存和加载模型参数,实现模型的迁移学习。
  • 模型重用:Class的封装性使得模型可以很容易地被其他项目或研究人员重用,加速PDE深度学习的研究和应用。
  1. 集成到PDE求解器中
  • 与传统方法结合:Class可以用于将深度学习模型集成到传统的PDE求解器中,形成混合求解方法。这种方法可以充分利用深度学习的非线性拟合能力和传统方法的稳定性、精确性等优点。
  • 模块化设计:通过Class的模块化设计,可以轻松地替换或升级PDE求解器中的不同组件(如求解器算法、网格划分策略等),以适应不同的PDE求解需求。

下面是代码举例

import numpy as np

class Exact:
    def __init__(self, xa, xb):
        self.xa = xa
        self.xb = xb

    def u_exact(self, X):
        
        u = np.sin(2*np.pi*X / (self.xb - self.xa))

        return u
class Dataset:
    def __init__(self, x_range, N_res, N_b, xa, xb):
        self.x_range = x_range
        self.N_res = N_res
        self.N_b = N_b
        self.xa = xa
        self.xb = xb

    def bc(self, X_b):
        U_bc = Exact(self.xa, self.xb)
        u_bc = U_bc.u_exact(X_b)
        return u_bc

    def build_data(self):
        x0 = self.x_range[0]
        x1 = self.x_range[1]

        Xmin = np.array([[x0]])
        Xmax = np.array([[x1]])

        ## For the equation, using the uniform mesh
        """
        N = self.N_res
        X_res_input = np.linspace(x0, x1, N).reshape((-1, 1))
        """

        ## For the equation, using the random mesh
        X_res_input = x0 + (x1-x0)*np.random.rand(self.N_res,1)

        #BC- x = xa, xb
        X_b0_input = np.array([[x0]])
        X_b1_input = np.array([[x1]])
        
        return X_res_input, X_b0_input, X_b1_input, Xmin, Xmax



在这个案例中,我们定义了两个类:Exact 和 Dataset。Exact 类用于计算一个精确解(在这个例子中是一个正弦波形),而 Dataset 类则用于构建和准备数据,这些数据可以用于训练或测试基于神经网络的PDE求解器或其他类型的数值方法。

Exact 类
__init__ 方法接受两个参数 xa 和 xb,这两个参数定义了正弦波函数的空间范围。
u_exact 方法接受一个数组 X,并返回该数组上正弦波的精确解。正弦波的频率由 (self.xb - self.xa) 决定,确保正弦波在一个周期内从 xa 到 xb。
Dataset 类
__init__ 方法接受 x_range(定义了解的空间范围),N_res(内部点数量),N_b(边界点数量,尽管在这个例子中没有直接使用),xa 和 xb(与 Exact 类中的意义相同)。
bc 方法计算边界点上的精确解。它首先创建一个 Exact 对象,然后使用该对象的 u_exact 方法来计算边界点 X_b 上的解。
build_data 方法构建了用于PDE求解的数据集。它首先定义了最小和最大的 x 值,然后构建了一个内部点集 X_res_input。这里有两种构建内部点集的方式:使用均匀网格或随机网格。本例中使用了随机网格,这可能在某些类型的数值方法(如蒙特卡洛方法)中更有用,但在大多数基于神经网络的PDE求解器中,可能更倾向于使用均匀网格。此外,它还定义了边界点 X_b0_input 和 X_b1_input,分别对应于 x_range 的起始和结束值。

打印测试代码

以下是一个简单的测试代码,它实例化 Dataset 类并打印出一些构建的数据集:

import numpy as np  
  
# 实例化 Dataset 类  
x_range = [0, 1]  # 定义解的空间范围  
N_res = 10        # 内部点数量  
N_b = 2           # 边界点数量(在这个例子中未直接使用)  
xa, xb = x_range  # 解的起始和结束点  
  
dataset = Dataset(x_range, N_res, N_b, xa, xb)  
  
# 调用 build_data 方法并打印结果  
X_res_input, X_b0_input, X_b1_input, Xmin, Xmax = dataset.build_data()  
  
print("内部点集 X_res_input:")  
print(X_res_input)  
print("边界点 X_b0_input:")  
print(X_b0_input)  
print("边界点 X_b1_input:")  
print(X_b1_input)  
print("最小 x 值 Xmin:")  
print(Xmin)  
print("最大 x 值 Xmax:")  
print(Xmax)  
  
# 可以选择性地计算并打印边界点的精确解  
u_b0 = dataset.bc(X_b0_input)  
u_b1 = dataset.bc(X_b1_input)  
print("边界点 X_b0_input 上的精确解 u_b0:")  
print(u_b0)  
print("边界点 X_b1_input 上的精确解 u_b1:")  
print(u_b1)

TensorFlow 语法基础

以下是一些基于 TensorFlow 1.15 版本的测试案例,涵盖了 tf.contrib(注意:tf.contrib 在 TensorFlow 2.x 中已被移除,因此这里仅为演示 1.x 版本中的用法)、tf.Variable、tf.placeholder 和 tf.Session() 的基本用法。每个测试案例都附有简要说明,概述了这些 TensorFlow 元素的意义和用途。

  1. 使用 tf.contrib(示例性,不推荐在 TensorFlow 2.x 中使用)
    注意:tf.contrib 包含了许多实验性和非官方的 TensorFlow 组件,这些组件在 TensorFlow 2.x 中已被移除或整合到核心库中。以下示例仅用于展示 1.x 版本中的用法。
import tensorflow as tf  
  
# 假设我们想要使用 tf.contrib.layers 中的某个函数,这里仅作为示例(不推荐使用)  
# 在 TensorFlow 2.x 中,类似的功能可能已经直接在 tf.keras.layers 中可用  
try:  
    # 注意:这里的函数仅作为示例,实际可能不存在或已迁移  
    weights = tf.contrib.layers.xavier_initializer()([5, 5])  
    print("Variable initialized with tf.contrib.layers:")  
    print(weights)  
except AttributeError:  
    print("tf.contrib is not available in TensorFlow 2.x. This is a 1.x example.")  
  
# 总结:tf.contrib 提供了额外的功能,但在 TensorFlow 2.x 中已不推荐使用。
  1. 使用 tf.Variable.
    TensorFlow中的变量是承载和更新参数的对象。变量必须初始化
import tensorflow as tf  
  
# 创建一个 TensorFlow 变量  
var = tf.Variable(3.0, name='my_variable')  
  
# 初始化所有变量  
init = tf.global_variables_initializer()  
  
# 启动 TensorFlow 会话  
with tf.Session() as sess:  
    sess.run(init)  
    print("Initialized variable:", sess.run(var))  
  
# 总结:tf.Variable 用于在 TensorFlow 图中定义可训练的参数。
  1. 使用 tf.placeholder. 占位符。
import tensorflow as tf  
  
# 创建一个占位符,用于后续输入数据  
x = tf.placeholder(tf.float32, shape=[])  
y = tf.square(x)  
  
# 启动 TensorFlow 会话  
with tf.Session() as sess:  
    # 运行图时,需要提供占位符的值  
    print("Square of 2:", sess.run(y, feed_dict={x: 2.0}))  
  
# 总结:tf.placeholder 用于在 TensorFlow 图中创建一个输入端口,允许在运行时动态输入数据。

TensorFlow 图和会话是很重要的概念,可以参考 参考视频第五集

import tensorflow as tf 
import numpy as np 
tensor_1d = np.array([1,2,3,4,5,6,7,8,9,10]) 
tensor_1d = tf.constant(tensor_1d) 
with tf.Session() as sess: 
     print(tensor_1d.get_shape()) 
     print(sess.run(tensor_1d))
    
tensor_2d = np.array([(1,2,3),(4,5,6),(7,8,9)]) 
tensor_2d = tf.Variable(tensor_2d) 
with tf.Session() as sess: 
	# 使用会话计算图中的计算,让流程图 “动起来”
     sess.run(tf.global_variables_initializer()) 
     print (tensor_2d.get_shape()) 
     print(sess.run(tensor_2d) )
  1. TensorFlow的TensorBoard是一个非常强大的可视化工具,它可以帮助用户理解和调试神经网络模型。以下是一个详细且全面的TensorBoard使用案例,涵盖了其基本功能和步骤:
import tensorflow as tf  
  
# 定义计算图  
a = tf.constant(2.0)  
b = tf.constant(3.0)  
c = a * b  
  
# 创建一个FileWriter来保存计算图  
log_dir = 'logs/'  
writer = tf.summary.FileWriter(log_dir, tf.get_default_graph())  
writer.close()  
  
# 假设我们有一个训练过程,我们需要记录损失值  
loss = tf.placeholder(tf.float32, shape=())  
summary = tf.summary.scalar('loss', loss)  
  
# 创建一个FileWriter来保存训练过程中的数据,可以避免长文输出
train_writer = tf.summary.FileWriter(log_dir + 'train', graph=None)  
  
with tf.Session() as sess:  
    # 初始化变量  
    tf.global_variables_initializer().run()  
  
    # 假设训练过程  
    for i in range(100):  
        # 模拟损失值  
        loss_value = i * 0.1  
  
        # 合并并写入摘要  
        summary_str = sess.run(summary, feed_dict={loss: loss_value})  
        train_writer.add_summary(summary_str, i)  
  
    train_writer.close()

这里笔者遇到一个问题:How can I run Tensorboard on a remote server? 目前没有解决,留待以后再看看了。

  • 10
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

计算小屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值