Shu's Garden - numpy
type: channel
link: https://www.sitstars.com/tag/numpy/
items: 0基础入门神经网络：递归神经网络(RNN)
items: 0基础入门神经网络：卷积神经网络(CNN)02
items: 0基础入门神经网络：卷积神经网络(CNN)01
items: Softmax的简单解释
items: 0基础入门神经网络：神经网络简介
items: 利用python进行数据收集、整理、分析和绘图的全过程

0基础入门神经网络：递归神经网络(RNN)
type: item
date: 2019-10-24T00:11:00+08:00
description: 原文地址为什么使用RNN？递归神经网络（Recurrent Neural Networks，RNN）是一种专门处理序列的神经网络。由于它们在处理文本方面的有效性，因此经常用于自然语言处理（NLP）任务。在本文中，我们将探讨RNN是什么，了解它们的工作原理，并在Python中从头开始构建一个真正的RNN。（仅使用numpy）。这篇文章假定您具有神经网络的基础知识。建议先阅读神经网络基础最原始（vanilla，原意为香草，在机器学习中等同于raw）的神经网络和CNNs存在一个问题：只能接受固定的输入并产生固定的输出。RNN则不同，它可以接受并输出可变长度序列，以下是RNN的一些例子： 输入为红色，RNN本身为绿色，输出为蓝色。资料来源：Andrej Karpathy这种处理序列的能力使RNN非常有用。例如：机器翻译（例如Google Translate）使用“多对多” 型RNN进行。原始文本序列输送到RNN，然后RNN生成翻译后的文本并输出。情绪分析（例如，这是正面还是负面的评价？）通常使用“多对一”的RNN进行。将要分析的文本输入到RNN中，然后生成一个单一的输出分类（例如，这是正面的评价）。在本文的后半部分，我们将构建一个“多对一”式的RNN，实现一个最简单的情感分析功能如何做？让我们考虑一个“多对多”式的RNN，它接受$x _ { 0 } , x _ { 1 } , \dots x _ { n }$的输入，并产生$y _ { 0 } , y _ { 1 } , \dots y _ { n }$的输出，xi和yi可以是任意维度的向量。RNN借助一个迭代更新的 隐状态（hidden state）h来工作，h也是一个任意维度的向量。在任意给定的步长t上，有：下一个 隐状态$h_t$通过先前的 隐状态$h_{t-1}$和下一个输入 $x_t$计算而来。下一个输出$y_t$由$h_t$计算而来。 一个多对多RNN这就是使RNN 反复出现的原因：它对每个步骤使用相同的权重。更具体地说，典型的原始RNN仅使用3组权重来执行其计算：$W_{xh}$用于所有的$x_t\to h_t$链接$W_{hh}$用于所有的$h_{t-1}\to h_t$链接$W_{hy}$用于所有的$h_t\to y_t$链接同时我们为RNN应用两个偏置（biases）：$b_h$，计算$h_t$的时候需要加上它。$b_y$，计算$y_t$的时候需要加上它。我们用矩阵表示权重，用向量表示偏置。这3个权重和2个偏置构成了整个RNN！以下是将所有内容组合在一起的方程式：$$\begin{array} { c } { h _ { t } = \tanh \left( W _ { x h } x _ { t } + W _ { h h } h _ { t - 1 } + b _ { h } \right) } \\ { y _ { t } = W _ { h y } h _ { t } + b _ { y } } \end{array}$$不要跳过这些方程式。停下来思考一下。另外，请记住，权重是矩阵，其他变量是向量。所有的权重都使用矩阵乘法，并且将偏置加到乘积结果中。然后，我们将tanh用作第一个方程式的激活函数（但是也可以使用S型等其他激活函数）。问题我们将从头开始实现RNN，以执行简单的情感分析任务：确定给定的文本字符串是正面的还是负面的。这是我为本文汇总的小型数据集的一部分：TextPositive?i am good✓i am bad❌this is very good✓this is not bad✓i am bad not good❌i am not at all happy❌this was good earlier✓i am not at all bad or sad right now✓计划由于这是一个分类问题，因此我们将使用“多对一” RNN。这类似于我们之前讨论的“多对多” RNN，但是它仅使用最终的 隐状态来输出y 多对一RNN每 个$x_i$将是一个向量，代表文本中的一个单词。输出$y$是一个包含两个数字的向量，一个代表正面，另一个代表负面。我们将用Softmax将这些值转换为概率，并最终确定正负。让我们开始构建我们的RNN！预处理我前面提到的数据集由两个Python字典组成：train_data = { 'good': True, 'bad': False, # ... more data } test_data = { 'this is happy': True, 'i am good': True, # ... more data }True = Positive, False = Negative我们必须进行一些预处理才能将数据转换为可用格式…

0基础入门神经网络：卷积神经网络(CNN)02
type: item
date: 2019-10-23T15:34:00+08:00
description: 原文地址在本文中，我们将深入探讨卷积神经网络（CNN）：如何训练CNN（包括梯度推导），从头实现反向传播（仅使用numpy）以及最终构建完整的训练！本文假定你对CNNs有基础了解，如果否，请参考CNN01本部分同时也要求你有多元微分的知识. 您可以根据需要跳过这些部分，但还是建议阅读它们，对写代码有用。开始我们从上一篇文章停下来的地方开始，我们正在使用CNN来解决MNIST手写数字识别问题： 来自MNIST数据集的样本图像我们（简单的）CNN由一个卷机层（Conv layer），一个最大池化层（Max Pooling layer）和一个Softmax层组成。下面是一个简单的示意图： Our (simple) CNN consisted of a Conv layer, a Max Pooling layer, and a Softmax layer. Here's that diagram of our CNN again:我们写了三个类, 分别是这三个层： Conv3x3, MaxPool, 和 Softmax. 每个类都有一个 forward() ，一种用于构建CNN前向传递的方法# Header: cnn.py conv = Conv3x3(8) # 28x28x1 -> 26x26x8 pool = MaxPool2() # 26x26x8 -> 13x13x8 softmax = Softmax(13 * 13 * 8, 10) # 13x13x8 -> 10 def forward(image, label): ''' Completes a forward pass of the CNN and calculates the accuracy and cross-entropy loss. - image is a 2d numpy array - label is a digit ''' # We transform the image from [0, 255] to [-0.5, 0.5] to make it easier # to work with. This is standard practice. out = conv.forward((image / 255) - 0.5) out = pool.forward(out) out = softmax.forward(out) # Calculate cross-entropy loss and accuracy. np.log() is the natural log. loss = -np.log(out[label]) acc = 1 if np.argmax(out) == label else 0 return out, loss, acc你可以阅读代码或 在浏览器中运行. 也可以在Github上找到它.下面是CNN的输出：MNIST CNN initialized! [Step 100] Past 100 steps: Average Loss 2.302 | Accuracy: 11% [Step 200] Past 100 steps: Average Loss 2.302 | Accuracy: 8% [Step 300] Past 100 steps: Average Loss 2.302 | Accuracy: 3% [Step 400] Past 100 steps: Average Loss 2.302 | Accuracy: 12%显然，我们希望能有10%以上的准确度……让我们训练CNN。训练概述训练神经网络通常包括两个阶段：一个前向阶段，其中输入完全通过神经网络。一个后向阶段，其中梯度被反向传播（backpropagated or backprop)，而且权重不断更新。我们将遵循这种模式来训练我们的CNN。我们还将使用两个主要特定于实现的想法：在前向阶段，每一层将缓存（cashe）任何后向阶段所需的任何数据（例如输入，中间值等）。这意味着任何后向阶段都必须在相应的前向阶段之前。在后向阶段，每一层将接收一个梯度（gradient）并且还返回一个梯度。它将获得相对于其输出的损失梯度 ($\frac{\partial L}{\partial \text{out}}$) ，并返回相对于其输入的损失梯度（$\frac{\partial L}{\partial \text{in}}$​).这两个想法将有助于保持我们训练的整洁有序。了解原因的最好方法可能是查看代码：# Feed forward out = conv.forward((image / 255) - 0.5) out = pool.forward(out) out =…

0基础入门神经网络：卷积神经网络(CNN)01
type: item
date: 2019-10-23T03:00:00+08:00
description: 原文链接在过去的几年里，关于卷积神经网络（Convolution Neural Networks，CNN）的讨论越来越多，特别是因为它彻底改变了计算机视觉领域。在本文中，我们将基于神经网络的基本背景知识，探索CNN是什么，了解它们的工作原理，并在Python中从头开始构建一个真正的CNN（仅使用numpy）。这篇文章仅假设你拥有神经网络的基本知识。我对神经网络的介绍涵盖了您需要了解的所有内容，因此您可能需要首先阅读它。为什么使用CNNCNN的经典案例是图像分类，例如查看宠物的图像并确定它是猫还是狗。那么问题来了，为什么不使用普通的神经网络？好问题原因1：图片很大如今，有关计算机视觉问题的图像通常为224x224或更大。想象一下，建立一个神经网络来处理224x224彩色图像：包括图像中的3个彩色通道（RGB），也就是说需要224 x 224 x 3 = 150528个输入特征！在这种网络中，典型的隐藏层可能有1024个节点，因此仅第一层就必须训练150,528 x 1024 = 150+百万个权重。我们的网络非常庞大，几乎无法训练。而且我们也不需要那么多的权重。我们知道像素在与其相邻的环境中最有用。图像中的对象由小的局部特征组成，例如眼睛的圆形虹膜或一张纸的方形角。第一个隐藏层中的每个节点查看每个像素是否很浪费？原因2：位置会发生变化如果你训练了一个网络来检测狗，你会希望它能够检测狗，而不管它出现在图像的什么地方。想象一下，训练一个网络，它能很好地处理一个特定的狗的图像，但是给它一个稍微改变了的图像。狗不会激活相同的神经元，所以网络的反应会完全不同！我们很快就会看到CNN如何帮助我们解决这些问题。数据集在本文中，我们将解决计算机视觉的“Hello, World!”：MNIST手写数字分类问题。很简单：给定图像，将其分类为数字。 MNIST数据集MNIST数据集中的每个图像均为28x28像素，并包含居中的灰度数字。说实话，一般的神经网络实际上可以很好地解决这个问题。您可以将每张图像视为28 x 28 = 784维向量，将其输入到784维输入层，堆叠一些隐藏层，最后得到10个节点的输出层，每个数字1个节点。但是它只会在MNIST数据集包含居中的小图像时起作用，本例中我们不会遇到上述尺寸或偏移问题。请记住，大多数现实世界中的图像分类问题并非易事。卷积什么是卷积神经网络？它是使用卷积层（又称为Conv层）的神经网络，其基于卷积的数学运算。Conv层由一组filter（卷积核）组成，您可以将其视为二维的数字矩阵。这是一个3x3卷积核示例： 我们可以输入图像和卷积核，将卷积核与输入图像卷积来生成输出图像。这包括在某些位置将卷积核覆盖在图像顶部。在卷积核中的值和图像中相应的值之间执行逐元素乘法（element-wise multiplication）。加总所有逐元素乘法的结果。和是输出图像中目标像素的输出值。在所有位置重复该过程。旁注：从技术上讲，我们（以及许多CNN）实际上在这里使用互相关而不是卷积，但是它们几乎是同一件事。我不会在这篇文章中介绍差异，因为它并不重要，但是如果您感到好奇，可以随时查找相关资料。这个四步描述有点抽象，所以让我们做一个例子。考虑一下这个微小的4x4灰度图像和3x3卷积核： 4x4图像（左）和3x3卷积核（右）图像中的数字表示像素强度，其中0为黑色，255为白色。我们将对输入图像和卷积核进行卷积以生成2x2的输出图像： 首先，让我们将卷积核覆盖在图像的左上角： 步骤1：将卷积核（右）覆盖在图像（左）的上方接下来，我们在重叠的图像值和卷积核值之间执行逐元素乘法。结果如下，从左到右，从上到下：图像值卷积核值结果0-1050000100-2080003126233-1-339000010步骤2：执行逐元素乘法。接下来，加总所有的结果，这很容易$$ 62 - 33 = \boxed{29} $$最后，我们将结果放置在输出图像的目标像素中。由于我们的卷积核覆盖在输入图像的左上角，因此我们的目标像素是输出图像的左上像素： 重复以上步骤，得到其他位置像素 它有什么用？让我们缩小一下，在更高的层次上看。将一个图像与一个卷积核进行卷积有什么用?我们可以从我们一直使用的3x3卷积核开始，它通常被称为垂直索伯滤波器 垂直索伯滤波器这是一个垂直索伯滤波器的示例： 图像与垂直索伯滤波器卷积类似地，还有一个水平索伯滤波器卷积： 水平索伯滤波器卷积 图像与水平索伯滤波器卷积看看发生了什么事？索伯滤波器是边缘检测算子（edge-detectors）。垂直索伯滤波器检测垂直边缘，而水平索伯滤波器检测水平边缘。现在可以轻松地解释输出图像：输出图像中的亮像素（值较高的像素）表明原始图像周围有很强的边缘。您能看到为什么边缘检测图像比原始图像更有用的原因吗…

Softmax的简单解释
type: item
date: 2019-10-23T00:34:58+08:00
description: 原文地址基础介绍Softmax将任意实数值转换为概率，这在机器学习中通常很有用。其背后的数学非常简单：给定一些数字，将它们作为 e) (一个数学常数) 的幂加总所有以e为底的指数，结果作为分母每个单独指数为分子概率等于分子除以分母更确切地说，Softmax对n个给定的$x_1 \ldots x_n$数字作以下转换 :$$ s(x_i) = \frac{e^{x_i}}{\sum_{j=1}^n e^{x_j}} $$输出始终在$[0, 1]$之间，并且加总为0.因此，它们形成一个概率分布。例子假设我们有数字-1、0、3和5。首先，我们计算分母：$$ \begin{aligned} \text{分母} &= e^{-1} + e^0 + e^3 + e^5 \\ &= \boxed{169.87} \\ \end{aligned} $$然后，我们可以计算分子和概率：$x$分子 ($e^x$)概率 ($\frac{e^x}{169.87}$)-10.3680.002010.006320.090.1185148.410.874x越大，概率越高。另外请注意，所有概率加起来为1.在Python中实现Softmax使用 numpy 实现起来非常容易:import numpy as np def softmax(xs): return np.exp(xs) / sum(np.exp(xs)) xs = np.array([-1, 0, 3, 5]) print(softmax(xs)) # [0.0021657, 0.00588697, 0.11824302, 0.87370431]np.exp() 将xs作为幂，e作为低为什么Softmax如此有用?想象建立一个 神经网络 来回答这个问题: 这张照片是狗还是猫？该神经网络的一种常见的设计是：它输出2个实数，一个表示小狗，另一个表示猫猫，并应用Softmax处理这些值。例如，假设网络输出 $[-1, 2]$:动物$x$$e^x$Probability概率狗-10.3680.047猫27.390.953这意味着我们的网络有95.3％的置信度相信图片是猫。Softmax让我们用概率回答分类问题，比简单的答案（例如，二进制是/否）更有用。

0基础入门神经网络：神经网络简介
type: item
date: 2019-10-22T16:59:00+08:00
description: 原文地址这可能会让您感到惊讶：神经网络并不复杂！“神经网络”一词经常被用作流行语，但实际上，它们通常比人们想象的要简单得多。这篇文章是针对初学者的，并假定机器学习基础为零。我们在Python中从头实现神经网络。让我们开始吧！构建基础：神经元（Neurons）首先，我们必须引入神经元这个概念，这是神经网络的基本单位。神经元接受输入，并对它们进行一些数学运算，然后输出。下面是双输入神经元的模型： 这里发生了三件事：首先，每个输入都乘以相应的权重：$$\begin{array} { l } { x _ { 1 } \rightarrow x _ { 1 } * w _ { 1 } } \\ { x _ { 2 } \rightarrow x _ { 2 } * w _ { 2 } } \end{array}$$接着，加权输入之和与偏置（bias）b相加：$$\left( x _ { 1 } * w _ { 1 } \right) + \left( x _ { 2 } * w _ { 2 } \right) + b$$最后，总和通过激活函数（activation function）传递：$$y = f \left( x _ { 1 } * w _ { 1 } + x _ { 2 } * w _ { 2 } + b \right)$$激活函数用于将无界输入转换为具有良好的、可预测形式的输出。常用的激活函数是S型函数： 这个S函数将无界的输入（$-\infty ,\infty$）转化成有界的输出（$0,1$），无穷小输出0，无穷大输出1.一个简单的例子假设我们有一个双输入神经元，使用S函数并有以下参数：$$\begin{array} { c } { w = [ 0,1 ] } \\ { b = 4 } \end{array}$$其中，$w = [ 0,1]$仅仅是将w1=0,w2=1写成向量形式。现在，让我们给定神经元一个输入$x=[2,3]$，并用点积的形式更简洁地写公式：$$\begin{aligned} ( w \cdot x ) + b & = \left( \left( w _ { 1 } * x _ { 1 } \right) + \left( w _ { 2 } * x _ { 2 } \right) \right) + b \\ & = 0 * 2 + 1 * 3 + 4 \\ & = 7 \\ y = f ( w \cdot x + b ) & = f ( 7 ) = 0.999 \end{aligned}$$也就是说，给定输入$x=[2,3]$，输出0.999。这种将输入向前传递以获得输出的过程我们称之为前馈（feedforward）神经元的代码实现我们将使用numpy来进行数学运算。import numpy as np def sigmoid(x): # Our activation function: f(x) = 1 / (1 + e^(-x)) return 1 / (1 + np.exp(-x)) class Neuron: def __init__(self, weights, bias): self.weights = weights self.bias = bias def feedforward(self, inputs): # Weight inputs, add bias, then use the activation function total = np.dot(self.weights, inputs) + self.bias return sigmoid(total) weights = np.array([0, 1]) # w1 = 0, w2 = 1 bias = 4 # b = 4 n = Neuron(weights, bias) x = np.array([2, 3]) # x1 = 2, x2 = 3 print(n.feedforward(x)) # 0.9990889488055994同样输出了0.999将神经元组合成神经网络神经网络无非就是一束连接在一起的神经元。一个典型的神经网络如下： 该网络有2个输入，一个包含2个神经元的隐藏层（h1和h2），以及一个带有1个神经元的输出层（o1）。注意o1的输入也就是h1,h2的输出，这也是它被称为神经网络的原因。隐藏层是输入（第一）层和输出（最后一个）层之间的任何层。可以有多个隐藏层！它的工作是将输入转换为输出层可以使用的东西。例子：前馈神经网络使用上图所示的网络，并假设所有神经元的权重相同 w = [0，1]，偏置也相同，b = 0，也有同样的S型激活函数。让h1,h2,o1表示它们所代表的神经元的输出。如果我们输入x=[2,…

利用python进行数据收集、整理、分析和绘图的全过程
type: item
date: 2019-10-22T00:04:36+08:00
description: 这是github上的一个项目，作为数据分析基础入门是非常好的，于是我把它译为中文，希望对大家有所帮助。原文地址代码均已在本地测试通过。要求在此存储库中，我将记录收集数据，处理数据并进行可视化的完整过程。该项目中使用的数据集是国家数据-社会保障卡应用中心的婴儿名字，其中包括1880年至2018年的记录。需要安装python3与以下库：Requests - 下载数据集.pandas - 进行数据分析.NumPy - 矩阵运算.Matplotlib - 绘图.seaborn - 美化图.获取数据import requests url = "https://www.ssa.gov/oact/babynames/names.zip" with requests.get(url) as response: with open("names.zip", "wb") as temp_file: temp_file.write(response.content)提示：如果因为网速等问题下载失败，可手动复制链接到浏览器中下载。这就将数据的zip包下载到我们电脑中了，它包括了各年份数据的txt文件与一个说明pdf文档，我们需要做的是读取txt文件，进行处理并保存到csv中。这个新的csv文件将成为我们的数据集，并将包含4个字段（年份，名称，性别和数量）import csv from zipfile import ZipFile # 这两个都是内置模块，无需安装 data_list = "year", "name", "gender", "count" # 此列表将保存我们的所有数据。我们使用标题行对其进行初始化。 with ZipFile("names.zip") as temp_zip: # 读取zip对象 for file_name in temp_zip.namelist(): # 读取文件列表 if ".txt" in file_name: # 只读取txt文档 with temp_zip.open(file_name) as temp_file: # 从压缩包中读取这个txt for line in temp_file.read().decode("utf-8").splitlines(): # 文件以二进制形式打开，我们使用utf-8对其进行解码，以便可以将其作为字符串进行操作。 # 准备好我们所需的数据字段并将其添加到列表中. line_chunks = line.split(",") year = file_name[3:7] name = line_chunks[0] gender = line_chunks[1] count = line_chunks[2] data_list.append([year, name, gender, count]) # 保存成csv csv.writer(open("data.csv", "w", newline="", encoding="utf-8")).writerows(data_list)首先我们声明一个data_list，它是一个二维数组。目的是为了稍后我们可以用csv.writer.writerows()方法保存到csv中。（我更喜欢用writerows()而不是writerow()，因为它更快）接下来的步骤都有注释，就不再赘述了。数据探索（Data Exploration）基础信息首先导入相关库import matplotlib.pyplot as plt import numpy as np import pandas as pd import seaborn as sns接着我们使用pandas.read_csv()方法读取csvdf = pd.read_csv("data.csv") # 由于我们的数据集非常简单，因此我们不需要设置任何特殊标志或额外参数，默认值就足够了。让我们从经典的df.head()和df.tail()方法开始，他们分别能查看数据集前几行和后几行。df.head() # 前五行 >>> year name gender count 0 1880 Mary F 7065 1 1880 Anna F 2604 2 1880 Emma F 2003 3 1880 Elizabeth F 1939 4 1880 Minnie F 1746 df.tail() # 后五行 >>> year name gender count 1957041 2018 Zylas M 5 1957042 2018 Zyran M 5 1957043 2018 Zyrie M 5 1957044 2018 Zyron M 5 1957045 2018 Zzyzx M 5这些样…