pytorch深度学习实践 1~2讲 作业一

本文介绍了深度学习的基础,强调了理解并使用框架文档的重要性。讲解了从人工智能的推理和预测角度出发,如何通过数据驱动学习算法。讨论了线性模型的训练过程,包括过拟合问题和损失函数的计算。同时,提到了使用matplotlib进行可视化以及如何扩展模型以包含偏置项。最后,给出了使用numpy和matplotlib进行三维绘图的实例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深度学习框架,要学会看文档。因为框架在不断迭代。

第一讲 人工智能

推理:
中午吃什么?根据外部信息推理。
穿什么?根据衣服场地等信息来推理。

预测:

根据信息,和一个抽象的概念结合起来。
根据🐱推测出来猫这个抽象的概念。
人类智能(使用算法)->人工智能

机器学习,基本上都是监督学习。

以往的算法课
算法的思维方式:穷举、贪心、分治、动态过程。这些都是人工设计出来算法。
机器学习的算法,来自于数据

基于规则的系统:有知识库,比如求原函数,定义了一些列规则,它包含一套计算导数等知识内容。可以根据这些规则,求解出原函数,人工智能的定义是实现一些类似人类智能活动的一些程序,所以基于规则的也是人工智能。

经典的机器学习:手工的特征提取变成向量,使之与输出之间建立映射函数(这个是学习的来的)
表示学习:特征是学习得来的。和映射关系的学习是分开的。
维度组织,两个feature上采样比一个feature上采样多一个数量级。高维空间特征降维到低维空间,保持高维空间的特征。 需要训练特征提取器。
深度学习:特征是简单的特征。设计额外的一层来提取特征。端到端的,训练是合在一起的。
https://www.jianshu.com/p/b1dcd8811326

浅层神经元和高层神经元处理不同级别的信息。分成感知形成。
pytorch是动态图。

第二讲 线性模型

1、数据集
2、model
3、训练
4、inferring

过拟合问题,希望模型泛化能力好。

线性模型:y= w*x
不同w下,计算其loss(MSE)

穷举法,观察得到其大致范围,然后穷举,得到其loss最小的那个w。

训练代码
Visdom :facebook开源的可视化工具包。
存盘:断点重开问题

import numpy as np
import matplotlib.pyplot as plt

x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]

def forward(x):
	return w * x

def loss(x, y):
	y_pred = forward(x)
	return (y - y_pred) * (y - y_pred)

w_list = []
mes_list = []
for w in np.arrange(0.0, 4.0, 0.1):
	print('w =',w)
	l_sum = 0
	for x_val, y_val in zip(x_data, y_data):
		y_pred_val = forward(x_val)
		loss_val = loss(x_val, y_val)
		l_sum += loss_val
		print('\t', x_val, y_val, y_pred_val,loss_val)
	print('MSE=',l_sum / 3)
	w_list.append(w)
	mse_list.append(l_sum/3)

作业:模型变成了y = x * w + b
需要做到的是,matplotlib文档,找下三维图绘制
此外是三维图绘制常用的np.meshgird()函数

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

fig = plt.figure()
ax = Axes3D(fig)
#模型是y = w*x + b
def forward(x):
    return w * x + b

def loss(x, y):
    y_pred = forward(x)
    return (y - y_pred) * (y - y_pred) 

x_data = [1.0,2.0,3.0]
y_data = [3.0,5.0,7.0]
#利用了广播机制,w和b都在另一维度上扩充了,故计算的时候可以一起计算。
W = np.arange(0.0, 4.0, 0.1)
B = np.arange(-2.0, 2.0, 0.1)
w, b = np.meshgrid(W,B,indexing='ij')
l_sum = 0 
for x_val, y_val in zip(x_data, y_data):
    y_pred_val = forward(x_val)
    l_sum += loss(x_val, y_val)
    
mse = l_sum/3
print(mse.shape)


ax.plot_surface(w, b, mse, rstride=1, cstride=1, cmap=plt.get_cmap('rainbow'))
<think>好的,我现在需要回答用户的问题:“C++分数怎么表示”。用户之前已经问过关于C++中除法保留小数的问题,现在可能是在继续学习如何处理数值运算,特别是分数的表示。我需要先理解用户的需求,然后组织一个清晰、详细的回答。 首先,用户想知道如何在C++中表示分数分数通常涉及分子和分母,比如1/2或3/4。C++本身没有内置的分数类型,所以需要自己实现或者使用现有的库。根据用户之前的提问,他们可能希望了解多种方法,包括基础的手动实现和更高级的库使用。 接下来,我需要考虑不同的方法来表示分数: 1. **结构体或类**:创建一个包含分子和分母的结构体或类,并实现基本的运算如加减乘除,以及约分功能。这是最基础的方法,适合教学目的,但需要用户自己处理各种细节,比如运算符重载和错误处理(比如分母为零的情况)。 2. **使用STL或标准库**:C++标准库中没有直接的分数类型,但可以通过数值类型和算法来处理分数运算,比如使用`std::pair`来存储分子和分母,并结合GCD算法来约分。这可能不够直观,但可以利用现有库函数简化部分逻辑。 3. **第三方库**:如Boost库中的`boost::rational`,这是一个成熟的分数处理库,提供了丰富的功能和运算符重载,适合需要高效和可靠解决方案的情况。用户可能需要安装和配置Boost库,但这是最推荐的方法之一。 4. **手动字符串处理**:将分数作为字符串处理,解析分子和分母,并进行运算。这种方法可能比较复杂且容易出错,不太推荐,但可以作为扩展内容提及。 接下来,我需要确定回答的结构。通常用户希望有逐步的说明,包括代码示例和注意事项。需要确保回答覆盖不同的实现方法,从简单到复杂,并指出优缺点。 需要注意用户可能的疑问点: - 如何处理分母为零的情况? - 如何实现分数的约分? - 运算符重载的具体实现? - 如何输出分数? - 第三方库的安装和使用方法? 然后,我需要验证每种方法的正确性。例如,结构体方法中,必须确保在构造函数中处理分母为零的异常,并在运算后进行约分。使用`std::pair`时,需要结合`std::gcd`来计算最大公约数,这在C++17及以上版本中可用。对于Boost库,需要确保用户了解如何安装和包含正确的头文件。 可能还需要比较不同方法的优缺点,比如手动实现的灵活性与第三方库的高效性和可靠性之间的权衡。此外,提醒用户注意浮点数与分数之间的转换可能带来的精度问题,比如浮点数无法精确表示某些分数。 最后,总结不同方法的应用场景,帮助用户根据需求选择合适的方法。比如,对于学习目的,手动实现结构体是有益的;对于实际项目,推荐使用Boost库。</think>在 C++ 中表示和操作分数(如 $\frac{3}{4}$ 或 $\frac{5}{2}$)需要自定义实现或依赖第三方库,因为标准库未提供原生的分数类型。以下是详细的实现方法及示例: --- ### **1. 基础方法:自定义结构体/类** 通过定义包含**分子**和**分母**的结构体,并手动实现运算逻辑: #### **步骤 1:定义分数结构体** ```cpp #include <iostream> #include <algorithm> // 用于计算最大公约数(GCD) struct Fraction { int numerator; // 分子 int denominator; // 分母 // 构造函数(自动约分) Fraction(int num, int den) : numerator(num), denominator(den) { if (den == 0) throw "分母不能为0!"; // 错误处理 simplify(); // 构造时自动约分 } // 约分函数(核心) void simplify() { int gcd = std::gcd(numerator, denominator); // C++17起支持std::gcd numerator /= gcd; denominator /= gcd; if (denominator < 0) { // 确保分母始终为正 numerator *= -1; denominator *= -1; } } // 运算符重载:加法 Fraction operator+(const Fraction& other) const { int new_num = numerator * other.denominator + other.numerator * denominator; int new_den = denominator * other.denominator; return Fraction(new_num, new_den); } // 其他运算符(减、乘、除)类似实现... }; ``` #### **步骤 2:使用示例** ```cpp int main() { try { Fraction a(3, 4); // 3/4 Fraction b(5, 6); // 5/6 Fraction c = a + b; // 3/4 + 5/6 = 19/12 std::cout << "结果: " << c.numerator << "/" << c.denominator << std::endl; } catch (const char* msg) { std::cerr << "错误: " << msg << std::endl; } return 0; } ``` **输出**: ``` 结果: 19/12 ``` --- ### **2. 使用标准库工具(`std::pair` + 算法)** 若不想定义结构体,可用 `std::pair<int, int>` 临时表示分数,并手动处理运算: #### **示例代码** ```cpp #include <iostream> #include <utility> // std::pair #include <numeric> // std::gcd // 约分函数 void simplify(int& num, int& den) { int gcd = std::gcd(num, den); num /= gcd; den /= gcd; if (den < 0) { num *= -1; den *= -1; } } int main() { int num1 = 3, den1 = 4; // 3/4 int num2 = 5, den2 = 6; // 5/6 // 加法运算:a/b + c/d = (ad + bc)/bd int new_num = num1 * den2 + num2 * den1; int new_den = den1 * den2; simplify(new_num, new_den); std::cout << "结果: " << new_num << "/" << new_den << std::endl; return 0; } ``` --- ### **3. 使用第三方库(推荐)** #### **(1) Boost.Rational** Boost 库提供了高性能的 `boost::rational<T>` 类型,支持任意整数类型的分数运算。 **安装与使用**: ```cpp #include <boost/rational.hpp> #include <iostream> int main() { boost::rational<int> a(3, 4); // 3/4 boost::rational<int> b(5, 6); // 5/6 boost::rational<int> c = a + b; std::cout << "结果: " << c.numerator() << "/" << c.denominator() << std::endl; return 0; } ``` #### **(2) 其他库** - **GMP(GNU
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值