目录

第1关:sklearn逻辑回归 - 手写数字识别

任务描述

数据简介

LogisticRegression

编程要求

shape=[-1, 8, 8]的解释;

测试说明

答案说明

train_image=train_image.reshape(-1,8*8)/255.0:

logreg=LogisticRegression(solver='newton-cg',max_iter=1000,C=1000):

第1关:sklearn逻辑回归 - 手写数字识别

本文彩色的为原文没有的是自己的批注

任务描述

本关任务:使用sklearn中的LogisticRegression类完成手写数字识别任务。

数据简介

本关使用的是手写数字数据集,该数据集有 1797 个样本,每个样本包括 8*8 像素(实际上是一条样本有 64 个特征,每个像素看成是一个特征,每个特征都是float类型的数值)的图像和一个 [0, 9] 整数的标签。

为下面题中的train_image。

为下面题中的train_label,

LogisticRegression

LogisticRegression中默认实现了 OVR ,因此LogisticRegression可以实现多分类。LogisticRegression的构造函数中有三个常用的参数可以设置:

solver:{'newton-cg' , 'lbfgs', 'liblinear', 'sag', 'saga'}, 分别为几种优化算法。默认为liblinear; C:正则化系数的倒数,默认为 1.0 ,越小代表正则化越强; max_iter:最大训练轮数,默认为 100 。

和sklearn中其他分类器一样,LogisticRegression类中的fit函数用于训练模型,fit函数有两个向量输入:

X:大小为 [样本数量,特征数量] 的ndarray,存放训练样本;所以后面要三维转二维 Y:值为整型,大小为 [样本数量] 的ndarray,存放训练样本的分类标签。

LogisticRegression类中的predict函数用于预测,返回预测标签,predict函数有一个向量输入:

X:大小为[样本数量,特征数量]的ndarray,存放预测样本。所以后面要三维转二维

LogisticRegression的使用代码如下:

编程要求

填写digit_predict(train_sample, train_label, test_sample)函数完成手写数字识别任务,其中:

train_image:训练集图像,类型为ndarray,shape=[-1, 8, 8]; train_label:训练集标签,类型为ndarray; test_image:测试集图像,类型为ndarray。

shape=[-1, 8, 8]的解释:

第一个维度(通常是批次大小或样本数量)的大小是未知的或动态的,用 `-1` 表示。在许多函数和方法中,特别是与机器学习库(如TensorFlow或PyTorch)相关的函数中,`-1` 常常用作占位符,表示该维度的大小应该自动计算。 - 第二个维度的大小是 `8`。 - 第三个维度的大小也是 `8`。  

测试说明

只需返回预测结果即可,程序内部会检测您的代码,预测正确率高于 0.97 视为过关。

答案说明

train_image=train_image.reshape(-1,8*8)/255.0:

1.为什么除255:

在图像处理中,像素值通常表示为一个0到255的整数,其中0表示黑色,255表示白色。这种表示方法是基于8位二进制数,因为2^8 = 256,所以每个像素值可以表示从0到255的256个不同的灰度级别。

在将图像数据输入到神经网络之前,通常需要进行归一化处理,即将像素值从0-255的范围缩放到0-1的范围。这样做有几个原因:

1. **数值稳定性**:许多机器学习算法,特别是梯度下降算法,在输入数据具有较小范围时表现更好。归一化可以确保所有特征都在相似的尺度上,从而避免某些特征对模型的影响过大。

2. **模型收敛速度**:归一化后的数据可以加快模型的训练速度,因为梯度下降会更快地收敛到最优解。

3. **模型性能**:在某些情况下,归一化可以提高模型的性能,因为它使得模型更容易学习数据的内在模式。

因此,在将图像数据作为输入传递给神经网络之前,我们通常将其除以255,以将其归一化到0到1的范围内。这样做不会改变图像中像素之间的相对亮度,只是将它们的数值范围缩放到一个更小的范围,从而使模型更容易学习。

2.reshape(-1,8*8)的意思:

一维的-1,同上面shape(-1,8,8)中的-1一样,因为大小未知作为占位符,会自己计算。

8*8:将原本两维的8,8。转换为一维8*8。

最后使三维数组变成二维数组。

3.reshape(-1,8*8)的另一种表示reshape(train_image.shape[0], -1):

其中第一个维度的大小是`train_image.shape[0]`,而第二个维度的大小是自动计算的。

具体地:

`train_image.shape[0]`获取`train_image`数组的第一个维度的大小,这通常表示样本数量或批次大小。对应shape(-1,8,8)的-1,由程序自己计算。

`-1`是一个占位符,它告诉`reshape`函数让该维度的大小自动计算,以便保持原始数组中的元素总数不变。计算出来就是8*8

举个例子,假设`train_image`是一个形状为`(100, 28, 28)`的NumPy数组,表示有100张28x28像素的图像。如果你执行以下操作:

```python reshaped_images = train_image.reshape(train_image.shape[0], -1) ```

`reshaped_images`的形状将会是`(100, 784)`。这是因为`train_image.shape[0]`的值是100,而`-1`被计算为`28 * 28 = 784`,以保持总元素数量不变(即`100 * 28 * 28 = 100 * 784`)。

这种重塑通常用于将图像数据从三维(样本数,高度,宽度)转换为二维(样本数,特征数),其中特征数是通过将高度和宽度相乘得到的。这在准备数据以输入到某些机器学习模型(特别是那些期望二维输入数据的模型)时非常有用。

logreg=LogisticRegression(solver='newton-cg',max_iter=1000,C=1000):

选择 `max_iter` 的值为 1000 而不是其他数字并不是随意的,而是基于一些考虑和因素。以下是一些可能的原因:

1. **经验法则**:在某些领域和应用中,1000 被认为是一个合理的迭代次数。这可能是基于过去的经验,即在这个迭代次数下,许多算法能够收敛到一个满意的解。

2. **计算资源和时间限制**:选择 `max_iter` 的值也要考虑到计算资源和时间的限制。太高的迭代次数可能会消耗大量的计算资源或时间,而太低的迭代次数可能无法得到满意的解。1000 可能是一个在计算效率和解的质量之间找到平衡的迭代次数。

3. **收敛速度**:对于某些算法,1000 次迭代可能是一个合理的估计,以确保算法有足够的时间来收敛到一个解。这取决于算法的收敛速度,以及问题的规模和难度。

4. **默认值**:在某些软件库或框架中,1000 可能被用作 `max_iter` 的默认值。这是因为开发者可能认为这个值在大多数情况下都是一个合理的选择,或者因为它在内部测试中表现得很好。

5. **可调整性**:设置 `max_iter` 为 1000 也给用户提供了一个起点,他们可以根据需要调整这个值。如果用户在实践中发现 1000 次迭代不够或过多,他们可以很容易地调整这个参数。

需要注意的是,`max_iter` 的最佳值取决于具体的算法、问题、数据集和硬件。因此,在选择 `max_iter` 的值时,通常建议进行一些实验和验证,以找到最适合特定情况的迭代次数。

2. **牛顿法(Newton's Method)**

**优点:**

* 收敛速度快,特别是对于二次函数和某些非线性函数。 * 适用于高维特征空间。

**缺点:**

* 需要计算二阶导数(Hessian矩阵),计算量大。 * 对于非凸函数,可能陷入局部最优解。 * 在某些情况下,Hessian矩阵可能不可逆或接近不可逆。  

至于其他两个参数目前我也不知道具体原因,那是我乱试出来的。后续如果我知道了我也会来更新。如果你知道欢迎在评论区留言谢谢!

相关阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。