-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsearch.xml
126 lines (60 loc) · 92.6 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>PyTorch初入门</title>
<link href="/2020/062719066.html"/>
<url>/2020/062719066.html</url>
<content type="html"><![CDATA[<h1 id="PyTorch第一步"><a href="#PyTorch第一步" class="headerlink" title="PyTorch第一步"></a>PyTorch第一步</h1><h2 id="1-Tensor"><a href="#1-Tensor" class="headerlink" title="1.Tensor"></a>1.Tensor</h2><pre><code class="python">from __future__ import print_functionimport torch as t</code></pre><pre><code class="python"># 构建 5x3 矩阵,只是分配了空间,未初始化x = t.Tensor(5, 3)x = t.Tensor([[1,2],[3,4]])x</code></pre><pre><code>tensor([[1., 2.], [3., 4.]])</code></pre><pre><code class="python"># 使用[0,1]均匀分布随机初始化二维数组x = t.rand(5, 3) x</code></pre><pre><code>tensor([[0.0626, 0.2190, 0.8587], [0.9044, 0.4278, 0.8374], [0.1144, 0.4394, 0.7455], [0.5614, 0.7953, 0.2981], [0.2485, 0.6495, 0.5445]])</code></pre><pre><code class="python">print(x.size()) # 查看x的形状x.size()[1], x.size(1) # 查看列的个数, 两种写法等价</code></pre><pre><code>torch.Size([5, 3])(3, 3)</code></pre><p>【注】torch.Size 是tuple对象的子类,因此它支持tuple的所有操作,如x.size()[0]</p><h3 id="加法"><a href="#加法" class="headerlink" title="加法"></a>加法</h3><pre><code class="python">y = t.rand(5, 3)# 加法的第一种写法x + y</code></pre><pre><code>tensor([[0.4237, 0.8735, 0.9449], [1.7534, 1.3813, 1.5050], [0.5260, 1.1490, 0.7811], [1.4929, 0.8446, 1.1280], [0.3338, 1.5457, 0.8867]])</code></pre><pre><code class="python"># 加法的第二种写法t.add(x, y)</code></pre><pre><code>tensor([[0.4237, 0.8735, 0.9449], [1.7534, 1.3813, 1.5050], [0.5260, 1.1490, 0.7811], [1.4929, 0.8446, 1.1280], [0.3338, 1.5457, 0.8867]])</code></pre><pre><code class="python"># 加法的第三种写法:指定加法结果的输出目标为resultresult = t.Tensor(5, 3) # 预先分配空间t.add(x, y, out=result) # 输入到resultresult</code></pre><pre><code>tensor([[0.4237, 0.8735, 0.9449], [1.7534, 1.3813, 1.5050], [0.5260, 1.1490, 0.7811], [1.4929, 0.8446, 1.1280], [0.3338, 1.5457, 0.8867]])</code></pre><pre><code class="python">print('最初y')print(y)print('第一种加法,y的结果')y.add(x) # 普通加法,不改变y的内容print(y)print('第二种加法,y的结果')y.add_(x) # inplace 加法,y变了print(y)</code></pre><pre><code>最初ytensor([[0.3611, 0.6546, 0.0862], [0.8490, 0.9535, 0.6677], [0.4116, 0.7096, 0.0356], [0.9315, 0.0494, 0.8299], [0.0853, 0.8961, 0.3422]])第一种加法,y的结果tensor([[0.3611, 0.6546, 0.0862], [0.8490, 0.9535, 0.6677], [0.4116, 0.7096, 0.0356], [0.9315, 0.0494, 0.8299], [0.0853, 0.8961, 0.3422]])第二种加法,y的结果tensor([[0.4237, 0.8735, 0.9449], [1.7534, 1.3813, 1.5050], [0.5260, 1.1490, 0.7811], [1.4929, 0.8446, 1.1280], [0.3338, 1.5457, 0.8867]])</code></pre><p>【注】函数名后面带下划线_ 的函数会修改Tensor本身。例如,x.add_(y)和x.t_()会改变 x,但x.add(y)和x.t()返回一个新的Tensor, 而x不变。</p><pre><code class="python"># Tensor的选取操作与Numpy类似:这里输出x的第1列(下标从0开始)数据print(x)print(x[:, 1])</code></pre><pre><code>tensor([[0.0626, 0.2190, 0.8587], [0.9044, 0.4278, 0.8374], [0.1144, 0.4394, 0.7455], [0.5614, 0.7953, 0.2981], [0.2485, 0.6495, 0.5445]])tensor([0.2190, 0.4278, 0.4394, 0.7953, 0.6495])</code></pre><p>Tensor还支持很多操作,包括数学运算、线性代数、选择、切片等等,其接口设计与Numpy极为相似。更详细的使用方法,会在第三章系统讲解。Tensor和Numpy的数组之间的互操作非常容易且快速。对于Tensor不支持的操作,可以先转为Numpy数组处理,之后再转回Tensor。</p><pre><code class="python">a = t.ones(5) # 新建一个全1的Tensora</code></pre><pre><code>tensor([1., 1., 1., 1., 1.])</code></pre><pre><code class="python">b = a.numpy() # Tensor -> Numpyb</code></pre><pre><code>array([1., 1., 1., 1., 1.], dtype=float32)</code></pre><pre><code class="python">import numpy as npa = np.ones(5)b = t.from_numpy(a) # Numpy->Tensorprint(a)print(b)</code></pre><pre><code>[1. 1. 1. 1. 1.]tensor([1., 1., 1., 1., 1.], dtype=torch.float64)</code></pre><p>Tensor和numpy对象共享内存,所以他们之间的转换很快,而且几乎不会消耗什么资源。但这也意味着,如果其中一个变了,另外一个也会随之改变。</p><pre><code class="python">b.add_(1) # 以`_`结尾的函数会修改自身print(a)print(b) # Tensor和Numpy共享内存</code></pre><pre><code>[2. 2. 2. 2. 2.]tensor([2., 2., 2., 2., 2.], dtype=torch.float64)</code></pre><p>如果你想获取某一个元素的值,可以使用scalar.item。 直接tensor[idx]得到的还是一个tensor: 一个0-dim 的tensor,一般称为scalar.</p><pre><code class="python">scalar = b[0]scalar</code></pre><pre><code>tensor(2., dtype=torch.float64)</code></pre><pre><code class="python">scalar.size() #0-dim</code></pre><pre><code>torch.Size([])</code></pre><pre><code class="python">scalar.item() # 使用scalar.item()能从中取出python对象的数值</code></pre><pre><code>2.0</code></pre><pre><code class="python">tensor = t.tensor([2]) # 注意和scalar的区别tensor,scalar</code></pre><pre><code>(tensor([2]), tensor(2., dtype=torch.float64))</code></pre><pre><code class="python">tensor.size(),scalar.size()</code></pre><pre><code>(torch.Size([1]), torch.Size([]))</code></pre><pre><code class="python"># 只有一个元素的tensor也可以调用`tensor.item()`tensor.item(), scalar.item()</code></pre><pre><code>(2, 2.0)</code></pre><p>此外在pytorch中还有一个和np.array 很类似的接口: torch.tensor, 二者的使用十分类似。</p><pre><code class="python">tensor = t.tensor([3,4]) # 新建一个包含 3,4 两个元素的tensor</code></pre><pre><code class="python">scalar = t.tensor(3)scalar</code></pre><pre><code>tensor(3)</code></pre><pre><code class="python">old_tensor = tensornew_tensor = old_tensor.clone()new_tensor[0] = 1111old_tensor, new_tensor</code></pre><pre><code>(tensor([3, 4]), tensor([1111, 4]))</code></pre><p>需要注意的是,t.tensor()或者tensor.clone()总是会进行数据拷贝,新tensor和原来的数据不再共享内存。所以如果你想共享内存的话,建议使用torch.from_numpy()或者tensor.detach()来新建一个tensor, 二者共享内存。</p><pre><code class="python">new_tensor = old_tensor.detach()new_tensor[0] = 1111old_tensor, new_tensor</code></pre><pre><code>(tensor([1111, 4]), tensor([1111, 4]))</code></pre><h2 id="2-autograd-自动微分"><a href="#2-autograd-自动微分" class="headerlink" title="2.autograd: 自动微分"></a>2.autograd: 自动微分</h2><p>深度学习的算法本质上是通过反向传播求导数,而PyTorch的autograd模块则实现了此功能。在Tensor上的所有操作,autograd都能为它们自动提供微分,避免了手动计算导数的复杂过程。</p><p>从0.4起, Variable 正式合并入Tensor, Variable 本来实现的自动微分功能,Tensor就能支持。读者还是可以使用Variable(tensor), 但是这个操作其实什么都没做。建议读者以后直接使用tensor.</p><p>要想使得Tensor使用autograd功能,只需要设置tensor.requries_grad=True.</p><pre><code class="python"># 为tensor设置 requires_grad 标识,代表着需要求导数# pytorch 会自动调用autograd 记录操作x = t.ones(2, 2, requires_grad=True)# 上一步等价于# x = t.ones(2,2)# x.requires_grad = Truex</code></pre><pre><code>tensor([[1., 1.], [1., 1.]], requires_grad=True)</code></pre><pre><code class="python">y = x.sum()y</code></pre><pre><code>tensor(4., grad_fn=<SumBackward0>)</code></pre><pre><code class="python">y.grad_fn</code></pre><pre><code><SumBackward0 at 0x25f3331b4c8></code></pre><pre><code class="python">y.backward() # 反向传播,计算梯度</code></pre><pre><code class="python"># y = x.sum() = (x[0][0] + x[0][1] + x[1][0] + x[1][1])# 每个值的梯度都为1x.grad</code></pre><pre><code>tensor([[1., 1.], [1., 1.]])</code></pre><p>注意:grad在反向传播过程中是累加的(accumulated),这意味着每一次运行反向传播,梯度都会累加之前的梯度,所以反向传播之前需把梯度清零。</p><pre><code class="python">y.backward()x.grad</code></pre><pre><code>tensor([[2., 2.], [2., 2.]])</code></pre><pre><code class="python"># 以下划线结束的函数是inplace操作,会修改自身的值,就像add_x.grad.data.zero_()</code></pre><pre><code>tensor([[0., 0.], [0., 0.]])</code></pre><pre><code class="python">y.backward()x.grad</code></pre><pre><code>tensor([[1., 1.], [1., 1.]])</code></pre><h2 id="3-神经网络"><a href="#3-神经网络" class="headerlink" title="3.神经网络"></a>3.神经网络</h2><p>Autograd实现了反向传播功能,但是直接用来写深度学习的代码在很多情况下还是稍显复杂,torch.nn是专门为神经网络设计的模块化接口。nn构建于 Autograd之上,可用来定义和运行神经网络。nn.Module是nn中最重要的类,可把它看成是一个网络的封装,包含网络各层定义以及forward方法,调用forward(input)方法,可返回前向传播的结果。</p><h3 id="定义网络"><a href="#定义网络" class="headerlink" title="定义网络"></a>定义网络</h3><p>定义网络时,需要继承nn.Module,并实现它的forward方法,把网络中具有可学习参数的层放在构造函数<strong>init</strong>中。如果某一层(如ReLU)不具有可学习的参数,则既可以放在构造函数中,也可以不放,但建议不放在其中,而在forward中使用nn.functional代替。</p><pre><code class="python">import torch.nn as nnimport torch.nn.functional as Fclass Net(nn.Module): def __init__(self): # nn.Module子类的函数必须在构造函数中执行父类的构造函数 # 下式等价于nn.Module.__init__(self) super(Net, self).__init__() # 卷积层 '1'表示输入图片为单通道, '6'表示输出通道数,'5'表示卷积核为5*5 self.conv1 = nn.Conv2d(1, 6, 5) # 卷积层 self.conv2 = nn.Conv2d(6, 16, 5) # 仿射层/全连接层,y = Wx + b self.fc1 = nn.Linear(16*5*5, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) # class torch.nn.Linear(in_features,out_features,bias = True ) # 对传入数据应用线性变换:y = A x+ b # 参数: # in_features - 每个输入样本的大小 # out_features - 每个输出样本的大小 # bias - 如果设置为False,则图层不会学习附加偏差。默认值:True def forward(self, x): # 卷积 -> 激活 -> 池化 x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) x = F.max_pool2d(F.relu(self.conv2(x)), 2) # reshape,‘-1’表示列是自适应 x = x.view(x.size()[0], -1) # relu 一种激活函数,f(x)=max(0,x) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return xnet = Net()print(net)</code></pre><pre><code>Net( (conv1): Conv2d(1, 6, kernel_size=(5, 5), stride=(1, 1)) (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1)) (fc1): Linear(in_features=400, out_features=120, bias=True) (fc2): Linear(in_features=120, out_features=84, bias=True) (fc3): Linear(in_features=84, out_features=10, bias=True))</code></pre><p>只要在nn.Module的子类中定义了forward函数,backward函数就会自动被实现(利用autograd)。在forward 函数中可使用任何tensor支持的函数,还可以使用if、for循环、print、log等Python语法,写法和标准的Python写法一致。</p><p>网络的可学习参数通过net.parameters()返回,net.named_parameters可同时返回可学习的参数及名称。</p><pre><code class="python">params = list(net.parameters())print(len(params))</code></pre><pre><code>10</code></pre><pre><code class="python">for name,parameters in net.named_parameters(): print(name,':',parameters.size())</code></pre><pre><code>conv1.weight : torch.Size([6, 1, 5, 5])conv1.bias : torch.Size([6])conv2.weight : torch.Size([16, 6, 5, 5])conv2.bias : torch.Size([16])fc1.weight : torch.Size([120, 400])fc1.bias : torch.Size([120])fc2.weight : torch.Size([84, 120])fc2.bias : torch.Size([84])fc3.weight : torch.Size([10, 84])fc3.bias : torch.Size([10])</code></pre><p>forward函数的输入和输出都是Tensor。</p><pre><code class="python">input = t.randn(1, 1, 32, 32)out = net(input)out.size()</code></pre><pre><code>torch.Size([1, 10])</code></pre><pre><code class="python">net.zero_grad() # 所有参数的梯度清零out.backward(t.ones(1,10)) # 反向传播</code></pre><p>需要注意的是,torch.nn只支持mini-batches,不支持一次只输入一个样本,即一次必须是一个batch。但如果只想输入一个样本,则用 input.unsqueeze(0)将batch_size设为1。例如 nn.Conv2d 输入必须是4维的,形如$nSamples \times nChannels \times Height \times Width$。可将nSample设为1,即$1 \times nChannels \times Height \times Width$。</p><h2 id="4-损失函数"><a href="#4-损失函数" class="headerlink" title="4.损失函数"></a>4.损失函数</h2><p>nn实现了神经网络中大多数的损失函数,例如nn.MSELoss用来计算均方误差,nn.CrossEntropyLoss用来计算交叉熵损失。</p><pre><code class="python">output = net(input) # 预测值target = t.arange(0,10).view(1,10).float() # 真实值criterion = nn.MSELoss() # 确定损失函数loss = criterion(output, target) # 计算损失loss # loss是个scalar,即 0-dim 的数组</code></pre><pre><code>tensor(28.3596, grad_fn=<MseLossBackward>)</code></pre><p>如果对loss进行反向传播溯源(使用gradfn属性),可看到它的计算图如下:</p><p>input -> conv2d -> relu -> maxpool2d -> conv2d -> relu -> maxpool2d<br> -> view -> linear -> relu -> linear -> relu -> linear<br> -> MSELoss<br> -> loss </p><p>当调用loss.backward()时,该图会动态生成并自动微分,也即会自动计算图中参数(Parameter)的导数。</p><pre><code class="python"># 运行.backward,观察调用之前和调用之后的gradnet.zero_grad() # 把net中所有可学习参数的梯度清零print('反向传播之前 conv1.bias的梯度')print(net.conv1.bias.grad)loss.backward()print('反向传播之后 conv1.bias的梯度')print(net.conv1.bias.grad)</code></pre><pre><code>反向传播之前 conv1.bias的梯度tensor([0., 0., 0., 0., 0., 0.])反向传播之后 conv1.bias的梯度tensor([ 0.0404, 0.0388, 0.1300, 0.0091, -0.0929, -0.0989])</code></pre><h2 id="5-优化器"><a href="#5-优化器" class="headerlink" title="5.优化器"></a>5.优化器</h2><p>在反向传播计算完所有参数的梯度后,还需要使用优化方法来更新网络的权重和参数,例如随机梯度下降法(SGD)的更新策略如下:<br>weight = weight - learning_rate * gradient<br>手动实现如下:<br>learning_rate = 0.01<br>for f in net.parameters():<br> f.data.sub_(f.grad.data * learning_rate)# inplace 减法<br>torch.optim中实现了深度学习中绝大多数的优化方法,例如RMSProp、Adam、SGD等,更便于使用,因此大多数时候并不需要手动写上述代码。</p><pre><code class="python">import torch.optim as optim#新建一个优化器,指定要调整的参数和学习率optimizer = optim.SGD(net.parameters(), lr = 0.01)# 在训练过程中# 先梯度清零(与net.zero_grad()效果一样)optimizer.zero_grad() # 计算损失output = net(input)loss = criterion(output, target)#反向传播loss.backward()#更新参数optimizer.step()</code></pre><h2 id="6-数据加载与预处理"><a href="#6-数据加载与预处理" class="headerlink" title="6.数据加载与预处理"></a>6.数据加载与预处理</h2><p>在深度学习中数据加载及预处理是非常复杂繁琐的,但PyTorch提供了一些可极大简化和加快数据处理流程的工具。同时,对于常用的数据集,PyTorch也提供了封装好的接口供用户快速调用,这些数据集主要保存在torchvison中。</p><p>torchvision实现了常用的图像数据加载功能,例如Imagenet、CIFAR10、MNIST等,以及常用的数据转换操作,这极大地方便了数据加载,并且代码具有可重用性。</p><h3 id="小试牛刀:CIFAR-10分类"><a href="#小试牛刀:CIFAR-10分类" class="headerlink" title="小试牛刀:CIFAR-10分类"></a>小试牛刀:CIFAR-10分类</h3><p>下面我们来尝试实现对CIFAR-10数据集的分类,步骤如下:</p><ol><li>使用torchvision加载并预处理CIFAR-10数据集</li><li>定义网络</li><li>定义损失函数和优化器</li><li>训练网络并更新网络参数</li><li>测试网络</li></ol><h4 id="CIFAR-10数据加载及预处理"><a href="#CIFAR-10数据加载及预处理" class="headerlink" title="CIFAR-10数据加载及预处理"></a>CIFAR-10数据加载及预处理</h4><p>CIFAR-101是一个常用的彩色图片数据集,它有10个类别: ‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’。每张图片都是$3\times32\times32$,也即3-通道彩色图片,分辨率为$32\times32$。</p><pre><code class="python">import torchvision as tvimport torchvision.transforms as transformsfrom torchvision.transforms import ToPILImageshow = ToPILImage() # 可以把Tensor转成Image,方便可视化</code></pre><pre><code class="python"># 第一次运行程序torchvision会自动下载CIFAR-10数据集,# 大约100M,需花费一定的时间,# 如果已经下载有CIFAR-10,可通过root参数指定# 定义对数据的预处理transform = transforms.Compose([ transforms.ToTensor(), # 转为Tensor transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # 归一化 ])# 训练集trainset = tv.datasets.CIFAR10( root='/home/cy/tmp/data/', train=True, download=True, transform=transform)trainloader = t.utils.data.DataLoader( trainset, # dataset:包含所有数据的数据集 batch_size=4, # batch_size:一批里面所包含的数据的数量 shuffle=True, # shuffle:是否打乱数据位置,当为Ture时打乱数据,全部抛出数据后再次dataloader时重新打乱。 num_workers=2) # num_workers:使用线程的数量,当为0时数据直接加载到主程序,默认为0。# 测试集testset = tv.datasets.CIFAR10( '/home/cy/tmp/data/', train=False, download=True, transform=transform)testloader = t.utils.data.DataLoader( testset, batch_size=4, shuffle=False, num_workers=2)classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')</code></pre><p>【注】</p><ol><li>ToTensor类是实现:Convert a PIL Image or numpy.ndarray to tensor的过程,在PyTorch中常用PIL库来读取图像数据,因此这个方法相当于搭建了PIL Image和Tensor的桥梁。另外要强调的是在做数据归一化之前必须要把PILImage转成Tensor,而其他resize或crop操作则不需要。</li><li>Normalize类是做数据归一化的,一般都会对输入数据做这样的操作</li><li>其他参数介绍可以参考这里链接:<a href="https://www.jianshu.com/p/1ae863c1e66d" target="_blank" rel="noopener">https://www.jianshu.com/p/1ae863c1e66d</a></li></ol><p>举个例子:<br>transform.ToTensor(),<br>transform.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))<br>以上面代码为例,ToTensor()能够把灰度范围从0-255变换到0-1之间,而后面的transform.Normalize()则把0-1变换到(-1,1).具体地说,对每个通道而言,Normalize执行以下操作:<br>image=(image-mean)/std<br>其中mean和std分别通过(0.5,0.5,0.5)和(0.5,0.5,0.5)进行指定。原来的0-1最小值0则变成(0-0.5)/0.5=-1,而最大值1则变成(1-0.5)/0.5=1.</p><p>Dataset对象是一个数据集,可以按下标访问,返回形如(data, label)的数据。</p><pre><code class="python">(data, label) = trainset[100]print(classes[label])# (data + 1) / 2是为了还原被归一化的数据show((data + 1) / 2).resize((100, 100))</code></pre><p>Dataloader是一个可迭代的对象,它将dataset返回的每一条数据拼接成一个batch,并提供多线程加速优化和数据打乱等操作。当程序对dataset的所有数据遍历完一遍之后,相应的对Dataloader也完成了一次迭代。</p><pre><code class="python">dataiter = iter(trainloader)images, labels = dataiter.next() # 返回4张图片及标签print(' '.join('%11s'%classes[labels[j]] for j in range(4)))show(tv.utils.make_grid((images+1)/2)).resize((400,100))</code></pre><h4 id="定义网络-1"><a href="#定义网络-1" class="headerlink" title="定义网络"></a>定义网络</h4><p>拷贝上面的LeNet网络,修改self.conv1第一个参数为3通道,因CIFAR-10是3通道彩图。</p><pre><code class="python">import torch.nn as nnimport torch.nn.functional as Fclass Net(nn.Module): def __init__(self): super(Net, self).__init__() self.conv1 = nn.Conv2d(3, 6, 5) self.conv2 = nn.Conv2d(6, 16, 5) self.fc1 = nn.Linear(16*5*5, 120) self.fc2 = nn.Linear(120, 84) self.fc3 = nn.Linear(84, 10) def forward(self, x): x = F.max_pool2d(F.relu(self.conv1(x)), (2, 2)) x = F.max_pool2d(F.relu(self.conv2(x)), 2) x = x.view(x.size()[0], -1) x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return xnet = Net()print(net)</code></pre><h4 id="定义损失函数和优化器-loss和optimizer"><a href="#定义损失函数和优化器-loss和optimizer" class="headerlink" title="定义损失函数和优化器(loss和optimizer)"></a>定义损失函数和优化器(loss和optimizer)</h4><pre><code class="python">from torch import optimcriterion = nn.CrossEntropyLoss() # 交叉熵损失函数# SGD 就是随机梯度下降# momentum 动量加速,在SGD函数里指定momentum的值即可optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) </code></pre><h4 id="训练网络"><a href="#训练网络" class="headerlink" title="训练网络"></a>训练网络</h4><p>所有网络的训练流程都是类似的,不断地执行如下流程:</p><ul><li>输入数据</li><li>前向传播+反向传播</li><li>更新参数</li></ul><p><strong>torch.set_num_threads(int): 设定用于并行化CPU操作的OpenMP线程数</strong></p><p>不设置,cpu51%,时间15ms</p><p>2的时候,cpu17%,时间15ms变为25ms</p><p>4的时候,cpu34%,时间17ms</p><p>8的时候,cpu67%</p><pre><code class="python">t.set_num_threads(8)for epoch in range(2): running_loss = 0.0 for i, data in enumerate(trainloader, 0): # 输入数据 inputs, labels = data # 梯度清零 optimizer.zero_grad() # forward + backward outputs = net(inputs) loss = criterion(outputs, labels) loss.backward() # 更新参数 optimizer.step() # 打印log信息 # loss 是一个scalar,需要使用loss.item()来获取数值,不能使用loss[0] running_loss += loss.item() if i % 2000 == 1999: # 每2000个batch打印一下训练状态 print('[%d, %5d] loss: %.3f' \ % (epoch+1, i+1, running_loss / 2000)) running_loss = 0.0print('Finished Training')</code></pre><p>此处仅训练了2个epoch(遍历完一遍数据集称为一个epoch),来看看网络有没有效果。将测试图片输入到网络中,计算它的label,然后与实际的label进行比较。</p><pre><code class="python">dataiter = iter(testloader)images, labels = dataiter.next() # 一个batch返回4张图片print('实际的label: ', ' '.join(\ '%08s'%classes[labels[j]] for j in range(4)))show(tv.utils.make_grid(images / 2 - 0.5)).resize((400,100))</code></pre><p>接着计算网络预测的label:</p><pre><code class="python"># 计算图片在每个类别上的分数outputs = net(images)# 得分最高的那个类_, predicted = t.max(outputs.data, 1)print('预测结果: ', ' '.join('%5s'\ % classes[predicted[j]] for j in range(4)))</code></pre><p>已经可以看出效果,准确率50%,但这只是一部分的图片,再来看看在整个测试集上的效果。</p><pre><code class="python">correct = 0 # 预测正确的图片数total = 0 # 总共的图片数# 由于测试的时候不需要求导,可以暂时关闭autograd,提高速度,节约内存with t.no_grad(): for data in testloader: images, labels = data outputs = net(images) _, predicted = t.max(outputs, 1) total += labels.size(0) correct += (predicted == labels).sum()print('10000张测试集中的准确率为: %d %%' % (100 * correct / total))</code></pre><p>10000张测试集中的准确率为: 53 %</p><p>训练的准确率远比随机猜测(准确率10%)好,证明网络确实学到了东西。</p><h2 id="总结:"><a href="#总结:" class="headerlink" title="总结:"></a>总结:</h2><p>对PyTorch的基础介绍至此结束。总结一下,本节主要包含以下内容。</p><ol><li>Tensor: 类似Numpy数组的数据结构,与Numpy接口类似,可方便地互相转换。</li><li>autograd/: 为tensor提供自动求导功能。</li><li>nn: 专门为神经网络设计的接口,提供了很多有用的功能(神经网络层,损失函数,优化器等)。</li><li>神经网络训练: 以CIFAR-10分类为例演示了神经网络的训练流程,包括数据加载、网络搭建、训练及测试。</li></ol><p><strong>参考书目:《深度学习框架 PyTorch 入门与实战》 陈云 编著</strong></p>]]></content>
<categories>
<category> 深度学习 </category>
</categories>
<tags>
<tag> pytorch </tag>
<tag> 深度学习 </tag>
</tags>
</entry>
<entry>
<title>使用hexo+GitHub搭建步骤</title>
<link href="/2020/06222291.html"/>
<url>/2020/06222291.html</url>
<content type="html"><![CDATA[<h1 id="使用hexo-GitHub搭建步骤"><a href="#使用hexo-GitHub搭建步骤" class="headerlink" title="使用hexo+GitHub搭建步骤"></a>使用hexo+GitHub搭建步骤</h1><h2 id="1-下载Git和Node-js"><a href="#1-下载Git和Node-js" class="headerlink" title="1. 下载Git和Node.js"></a><strong>1. 下载Git和Node.js</strong></h2><hr><h3 id="1-1-Node-js的安装与配置"><a href="#1-1-Node-js的安装与配置" class="headerlink" title="1.1 Node.js的安装与配置"></a><strong>1.1 Node.js的安装与配置</strong></h3><p><strong>(1) 下载安装包</strong></p><p>node.js下载网址: <a href="https://nodejs.org/en/download/" target="_blank" rel="noopener">https://nodejs.org/en/download</a></p><p>下载完成后,双击安装:点击next,选择安装路径,</p><p><img src="https://img-blog.csdnimg.cn/20200621235502146.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20200621235528347.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20200621235555449.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20200621235639833.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p> <strong>(2)添加环境变量</strong></p><p>安装完成后,打开cmd验证安装情况:如下图,输入 node -v ,显示版本号则表明安装成功。(注;安装成功的同时也说明了nodejs已经添加到环境变量path中)<br><img src="https://img-blog.csdnimg.cn/20200622001329926.png" alt="在这里插入图片描述"></p><hr><p><strong>(3)接下来,需要设置npm的镜像源</strong></p><pre><code>- 查看npm的配置npm config list- 默认源npm config set registry [https://registry.npmjs.org](https://registry.npmjs.org/)- 临时改变镜像源npm --registry=[https://registry.npm.taobao.org](https://registry.npm.taobao.org/)- 永久设置为淘宝镜像源npm config set registry [https://registry.npm.taobao.org](https://registry.npm.taobao.org/)- 设置淘宝镜像源还可以使用另一种方式,编辑 ~/.npmrc 加入下面内容registry = [https://registry.npm.taobao.org](https://registry.npm.taobao.org/)</code></pre><p><img src="https://img-blog.csdnimg.cn/20200622001418727.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/20200622001433469.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><hr><p><strong>(4)设置npm的内置路径——>全局模块路径和缓存路径(建议**</strong>)**</p><p> 如果不改变内置路径也可,除非你的C盘空间足够bigger,这一步可以略过,不改变的话,它的路径在:</p><pre><code>- npm包全局目录:C:/Users/[username]/AppData/Roaming/npm/node_modules- npm包全局命令目录:C:/Users/[username]/AppData/Roaming/npm- npm实际去找全局命令的目录:C:/Users/[username]/.npmrc 文件内容的prefix值- npm包全局cache目录:C:/Users/[username]/.npmrc 文件内容的cache值</code></pre><p>首先在你Node.js的安装位置,新建两个文件夹,node_global和node_cache</p><p>然后分别执行的命令就是:</p><pre><code>npm config set prefix"C:\Program Files\nodejs\node_global"npm config set cache "C:\Program Files\nodejs\node_cache"</code></pre><p><img src="https://img-blog.csdnimg.cn/20200622001603511.png" alt="在这里插入图片描述"></p><p><strong>(5)修改用户变量</strong><br>然后在配置环境变量,右击我的电脑 ->属性 -> 高级系统设置 -> 环境变量同样的位置,在用户变量的地方,找到path变量进行修改,修改值如下图:<br>使用<br><img src="https://img-blog.csdnimg.cn/20200622001832717.png" alt="在这里插入图片描述"><br>替换<br><img src="https://img-blog.csdnimg.cn/20200622001735455.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>至此,node.js 安装完成。</p><hr><h3 id="1-2-Git的安装与配置"><a href="#1-2-Git的安装与配置" class="headerlink" title="1.2 Git的安装与配置"></a><strong>1.2 Git的安装与配置</strong></h3><p>下载地址: <a href="https://git-scm.com/downloads" target="_blank" rel="noopener">https://git-scm.com/downloads</a></p><ul><li><p>(1)下载,然后点击安装包进行安装,一切默认即可<br><img src="https://img-blog.csdnimg.cn/20200622001930240.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p></li><li><p>(2)在cmd中敲 git 和 git –version ,如下图则表明安装成功。<br><img src="https://img-blog.csdnimg.cn/20200622001947566.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p></li></ul><hr><h2 id="2、Github注册以及Github-Pages创建"><a href="#2、Github注册以及Github-Pages创建" class="headerlink" title="2、Github注册以及Github Pages创建"></a><strong>2、Github注册以及Github Pages创建</strong></h2><p>这里就不多介绍了。</p><hr><h2 id="3、配置Git用户名和邮箱"><a href="#3、配置Git用户名和邮箱" class="headerlink" title="3、配置Git用户名和邮箱"></a><strong>3、配置Git用户名和邮箱</strong></h2><p>在桌面点击鼠标右键,点击Git Bash Here</p><p><img src="https://img-blog.csdnimg.cn/20200622002028820.png" alt="在这里插入图片描述"></p><p>然后分别输入下面的两个命令,并回车:</p><p><img src="https://img-blog.csdnimg.cn/20200622002047133.png" alt="在这里插入图片描述"></p><hr><h2 id="4、本地安装hexo静态博客框架以及发布到Github-Pages"><a href="#4、本地安装hexo静态博客框架以及发布到Github-Pages" class="headerlink" title="4、本地安装hexo静态博客框架以及发布到Github Pages"></a><strong>4、本地安装hexo静态博客框架以及发布到Github Pages</strong></h2><p>首先选择一个磁盘作为你博客文件的存放位置,然后新建一个文件夹,比如名为blogtest的文件夹,创建完后,先不要点进去,在此处点击鼠标右键,选择Git Bash Here,然后依次输入如下命令:<br><img src="https://img-blog.csdnimg.cn/20200622002110552.png" alt="在这里插入图片描述"></p><p>注意,这里不知道是不是安装node.js时使用的是自定义路径,在执行了 npm install -g hexo-cli 后,也无法使用 hexo 命令,一直报错。</p><p><img src="https://img-blog.csdnimg.cn/20200622002127190.png" alt="在这里插入图片描述"></p><p>经查询(参考<a href="https://blog.csdn.net/qq_42893625/article/details/100852221" target="_blank" rel="noopener">https://blog.csdn.net/qq_42893625/article/details/100852221</a>):使用如下命令后安装成功:<br><img src="https://img-blog.csdnimg.cn/20200622002309330.png" alt="在这里插入图片描述"></p><p>最后解释一下,为啥要在前面加上npx。</p><p> 在大牛阮一峰的网络日志中,他是这么描述的:“npx 想要解决的主要问题,就是调用项目内部安装的模块”,所以可以理解为在命令行下调用,可以让项目内部安装的模块用起来更方便,npx运行的时候,会到node_modules/.bin路径和环境变量$PATH里面,检查命令是否存在,所以系统命令也可以调用,即上面的命令安装不成功的时候加上npx的话也许就可以成功了哦~</p><p><img src="https://img-blog.csdnimg.cn/20200622002338295.png" alt="在这里插入图片描述"></p><p>浏览器中打开<a href="http://locakhost:4000/" target="_blank" rel="noopener">http://locakhost:4000</a>或者127.0.0.1:4000,可以看到一个网页,说明Hexo博客已经成功在本地运行</p><hr><h2 id="5、-本地博客发布到Github-Pages"><a href="#5、-本地博客发布到Github-Pages" class="headerlink" title="5、 本地博客发布到Github Pages"></a><strong>5、 本地博客发布到Github Pages</strong></h2><h3 id="5-1"><a href="#5-1" class="headerlink" title="5.1"></a>5.1</h3><p>首先需要安装发布的插件,在站点目录下执行下面的命令,也就是创建的博客目录下:</p><pre><code>npm install hexo-deployer-git --save</code></pre><p><img src="https://img-blog.csdnimg.cn/20200622002404181.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><h3 id="5-2"><a href="#5-2" class="headerlink" title="5.2"></a>5.2</h3><p>紧接着,将本地目录与GitHub关联起来,输入下面的命令行:</p><pre><code>ssh-keygen -t rsa -C "邮箱地址"</code></pre><p>输入后一直回车,</p><p><img src="https://img-blog.csdnimg.cn/20200622002424186.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>然后在C:/Users/[username]目录下找到名为.ssh的文件夹, 文件夹内会有两个文件,一个id_rsa.pub一个id_rsa,用文本编辑器打开id_rsa.pub,复制里面的的内容。 然后打开Github,点击右上角的头像 Settings 选择SSH and GPG keys,添加ssh key 。</p><p>然后回到Git的命令行界面,测试一下是否与GitHub连接成功。输入下面的命令行:</p><pre><code>ssh -T [[email protected]](mailto:[email protected])</code></pre><p>点击回车,然后会出现一个询问内容,输入yes,回车,会出现一段内容,</p><p>Hi <account name>! You’ve successfully authenticated, but GitHub doesnot provide shell access.。</account></p><p> 说明连接成功。此处这个<account name>应该是你Github的用户名。</account></p><p><img src="https://img-blog.csdnimg.cn/2020062200250795.png" alt="在这里插入图片描述"></p><h3 id="5-3"><a href="#5-3" class="headerlink" title="5.3"></a>5.3</h3><p>进入博客站点目录,用文本编辑器打开_config.yml,这个_config.yml是博客的配置文件,在以后的博客修改,如个性化修改,博客SEO优化等都会使用到,修改如下图的几个地方:</p><p><img src="https://img-blog.csdnimg.cn/20200622002526361.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>滑到文件最底部,有一个deploy,在deploy下面添加一个repo项 ,一个branch项。填入如下代码,并如下图所示:<br><img src="https://img-blog.csdnimg.cn/20200622002553334.png" alt="在这里插入图片描述"><br><img src="https://img-blog.csdnimg.cn/2020062200260625.png" alt="在这里插入图片描述"></p><h3 id="5-4"><a href="#5-4" class="headerlink" title="5.4"></a>5.4</h3><p>生成页面,并发布至Github Pages,执行如下命令:<br><img src="https://img-blog.csdnimg.cn/20200622002640421.png" alt="在这里插入图片描述"></p><p>上传完成后,在浏览器中打开<strong>https://<用户名>.github.io</strong>,查看上传的网页。如果页面变成了之前本地调试时的样子,说明上传以及完成了。没变的话查看一下上传时命令行窗口的信息有没有错误信息,没有的话清除一下浏览器缓存试试。</p><p><img src="https://img-blog.csdnimg.cn/2020062200265536.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70" alt="在这里插入图片描述"></p><p>注:这几天一直使用的npx hexo 来当命令,直接使用报错,网上说是因为没用添加hexo 下的 node_modules.bin 文件<br>到环境变量中,但是我是加了这个到系统变量path中的,没起作用。<br>今天我又去这个文件夹下面找了一下,果然,里面有个命名为hexo文件,嗯,那应该就是添加这个了文件夹了。<br>于是了,我复制了目录,替换了原先的那个,保存后发现居然行了,额,真无语。</p><p>参考链接:<a href="https://blog.csdn.net/qq_42893625/article/details/100852221" target="_blank" rel="noopener">https://blog.csdn.net/victoryxa/java/article/details/103733655</a></p>]]></content>
<categories>
<category> 学习尝试 </category>
</categories>
<tags>
<tag> 博客搭建 </tag>
</tags>
</entry>
<entry>
<title>MyBlog前端开发2</title>
<link href="/2020/062137065.html"/>
<url>/2020/062137065.html</url>
<content type="html"><![CDATA[<h1 id="MyBlog个人博客前端开发(二)"><a href="#MyBlog个人博客前端开发(二)" class="headerlink" title="MyBlog个人博客前端开发(二)"></a>MyBlog个人博客前端开发(二)</h1><p>作者:silence</p><p>编写日期:2020-06-20</p><p>分类:学习记录</p><p>项目演示地址:<a href="https://silence-moon.github.io/hsilence.github.io-blog/index.html">MyBlog演示地址</a></p><hr><h2 id="一、前言"><a href="#一、前言" class="headerlink" title="一、前言"></a>一、前言</h2><p>昨天我们介绍了个人博客开发的背景、系统叙述、功能介绍以及首页的开发,我们主要说了如何做,至于具体的代码<br>部分并没有说,今天我们就来讲一讲。</p><h2 id="二、正文"><a href="#二、正文" class="headerlink" title="二、正文"></a>二、正文</h2><h3 id="2-1-导航栏"><a href="#2-1-导航栏" class="headerlink" title="2.1 导航栏"></a>2.1 导航栏</h3><p>整个导航的代码如下:</p><pre><code class="html"><!-- 导航 --><!-- 使用UI组件,使用inverted反转默认颜色,attached去圆角,segment表明这是一个片段,自定义上下内边距 --><nav id="nav" class="ui inverted attached segment m-padding-tb-mini"> <div class="ui container"> <!-- 为了适应移动端,这里需要加一个属性stackable,表示可堆叠 --> <div class="ui inverted secondary stackable menu"> <!-- 添加logo,导航菜单 --> <h2 class="ui teal header item">Blog</h2> <a href="index.html" class="menu-item item m-mobile-hide"><i class="home icon"></i>首页</a> <a href="#" class="menu-item item m-mobile-hide"><i class="idea icon"></i>分类</a> <a href="#" class="menu-item item m-mobile-hide"><i class="tags icon"></i>标签</a> <a href="# " class="menu-item item m-mobile-hide"><i class="clone icon"></i>归档</a> <a href="#" class="menu-item item m-mobile-hide"><i class="info icon"></i>关于我</a> <div class="right menu-item item m-mobile-hide"> <div class="ui icon input"> <input type="text" placeholder="Search..."/> <i class="search link icon"></i> </div> </div> </div> </div> <!-- 设置手机端响应时显示个菜单图标 --> <a href="#" class="ui menu toggle black icon button m-right-top m-mobile-show"> <i class="sidebar icon"></i> </a></nav></code></pre><p>在这里我们使用了semantic ui,这里有2种方法可以进行引用:</p><ul><li>(1).下载插件到本地:<ul><li>具体方法见<a href="https://semantic-ui.com/introduction/getting-started.html" target="_blank" rel="noopener">semantic ui</a></li></ul></li><li>(2).使用cdn直接引用:<ul><li>引用下面的script脚本即可</li></ul></li></ul><pre><code class="CSS"><link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css"></code></pre><pre><code class="JavaScript"><script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script></code></pre><p>对上述代码拆分一下,我们可以发现其可以分成如下几个部分:</p><p>(1).外部盒子</p><pre><code class="HTML"><nav id="nav" class="ui inverted attached segment m-padding-tb-mini"> <div class="ui container"> </div></nav></code></pre><p>这个外部盒子说白了就是一个容器,嗯,这个nav标签暂时可以加,也可以不加,只是成品上面会用得着,<br>就先加着吧。 class里面的 ui 说明这里使用的是 semantic ui 的 ui 组件,然后,这里为了简便,<br>直接使用 inverted 将背景设置成黑色(注:默认是白色,而 inverted 是置反的意思),<br>attached 一般的用法是将上下连在一起,如下图所示:<br><img src="https://img-blog.csdnimg.cn/20200621125732789.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70#pic_center" alt="在这里插入图片描述"><br>这里的“文章列表”框里,顶部的“博客”、“共**篇”和下方的文章内容是连在一起的,就是使用的attached这个<br>属性,segment说明这是一个段,m-padding-tb-mini 是在me.css中自定义的一个样式,顾名思义,就是<br>自定义的内边距,关于上下的(t:top;b:bottom)的一个mini值,当然,除了mini外,还有tiny、small、<br>normal(不写即为normal)、large、big、huge、massive等等几个级别,嗯,反正就是一组样式了,给自己<br>定义好一个规则之后,以后不就可以偷点懒,直接拿来用了嘛!</p><p>(2).内部的菜单和搜索框</p><pre><code class="HTML"><!-- 为了适应移动端,这里需要加一个属性stackable,表示可堆叠 --><div class="ui inverted secondary stackable menu"> <!-- 菜单部分 --> <!-- 搜索 --> <div class="right menu-item item m-mobile-hide"> <div class="ui icon input"> <input type="text" placeholder="Search..."/> <i class="search link icon"></i> </div> </div></div></code></pre><p>这里的 secondary 是一个颜色,stackable是表示可堆叠的意思,是为了适应移动端而写的,<br>menu说明这是一个菜单,下面的menu-item 表示这是一个菜单子项,是一个常识写法,为了让<br>搜索框向右浮动,这里写了right,嗯,这就是使用组件的好处了,如果是纯HTML+css,就应该<br>要加一个float了,然后是一个input输入框,为了在里面显示个搜索的小图标,这里写了search link icon。</p><h3 id="2-2-底部栏"><a href="#2-2-底部栏" class="headerlink" title="2.2 底部栏"></a>2.2 底部栏</h3><p>先放代码:</p><pre><code class="HTML"><footer class="ui inverted vertical segment m-padding-tb-massive"> <div class="ui center aligned container"> <div class="ui inverted divided stackable grid"> <div class="three wide column"> <h4 class="ui inverted header">扫码关注</h4> <div class="ui inverted link list"> <div class="item"> <!-- 图片设置为圆角,并使用内联样式控制图片大小 --> <img src="img/MyBlog.png" class="ui rounded image m-div-mini" alt=""> </div> </div> </div> <div class="three wide column"> <h4 class="ui inverted header">最新博客</h4> <div class="ui inverted link list"> <a href="#" class="item">用户故事(User Story)</a> </div> </div> <div class="three wide column"> <h4 class="ui inverted header">联系我</h4> <div class="ui inverted link list"> <a href="#" class="item">Email:[email protected]</a> </div> </div> <div class="seven wide column"> <h4 class="ui inverted header">Blog</h4> <p class="m-text-thin m-text-spaced m-opacity-mini">这是我的个人博客,会分享关于编程、思考等等相关的任何内容,希望可以对来到此站的朋友有所帮助!</p> </div> </div> <div class="ui inverted section divider"></div> <p class="m-text-thin m-text-spaced m-opacity-tiny">Copyright 2020 silence Designed by silence</p> </div></footer> </code></pre><p>然后我们来拆一下看看。外面还是个container容器,老套路,只是使用了center aligned增加了内容居中。<br>然后呢,使用了一个grid将上方分成四个分别占有3、3、3、7份的部分,分别放置图片和内容。</p><pre><code class="HTML"><div class="three wide column"> <h4 class="ui inverted header">扫码关注</h4> <div class="ui inverted link list"> <div class="item"> <!-- 图片设置为圆角,并使用内联样式控制图片大小 --> <img src="img/MyBlog.png" class="ui rounded image m-div-mini" alt=""> </div> </div></div></code></pre><p>图片的话是是list中的一项(item),是一个圆角rounded image图片,如果还有其他项,可以写下去。</p><p>就比如说第二个吧,“最新博客”下面,继续放上a标签写多个。</p><h3 id="2-3-右侧工具栏"><a href="#2-3-右侧工具栏" class="headerlink" title="2.3 右侧工具栏"></a>2.3 右侧工具栏</h3><pre><code class="HTML"><!-- 右侧工具栏 --><div class=""> <!-- 目录、返回顶部等等右侧小工具 --> <div id="toolBar" class=" m-position-fixed m-position-rb" style="display: none;"> <div class="ui vertical icon buttons"> <button type="button" class="ui toc teal button">目录</button> <!-- <a href="#comment-container" class="ui teal button">留言</a> --> <button class="ui addr_qrcode icon button" title="点我生成二维码,在手机上查看"><i class="qrcode icon"></i></button> <!-- 返回顶部图标 --> <div id="toTop-Btn" class="ui button" title="返回顶部"><i class="chevron up icon" style="margin: auto !important;"></i></div> </div> </div> <!-- 目录存放位置 --> <div class="ui toc-container flowing popup transition hidden" style="width: 15.625rem !important;"> <ol class="js-toc"> </ol> </div> <!-- 二维码存放位置 --> <div id="qrcode" class="ui QRcode flowing popup transition hidden" style="width: 130px !important;"> </div></div></code></pre><p>当然,这里就需要配置其他东西了,比如说生成二维码,你需要引入qrcode,生成目录的话需要引用tocbot等等。<br>虽然这里并不需要目录,但是为了统一性还是写上吧,而且在博客详情页面也还是需要用上的。</p><pre><code class="CSS"><!-- 引入tocbot.css实现自动生成目录 --><link rel="stylesheet" type="text/css" href="lib/tocbot/tocbot.css"/></code></pre><pre><code class="JavaScript"><!-- 引用tocbot.js实现自动生成目录 --> <script src="lib/tocbot/tocbot.js"></script> <!-- 引用qrcode.js实现自动生成当前地址的二维码 --> <script src="lib/qrcode/qrcode.js"></script> <!-- 引用jquery.waypoints.min.js实现滚动侦测 --> <script src="lib/waypoints/jquery.waypoints.min.js"></script></code></pre><pre><code class="JavaScript"><script> // 手机端点击menu按钮时显示菜单 $('.menu.toggle').click(function(){ // 点击按钮时检测menu-item内是否有m-mobile-hide属性,有则删除,没有则添上 $('.menu-item').toggleClass('m-mobile-hide'); }); //tocbot自动生成目录 //初始化tocbot tocbot.init({ // Where to render the table of contents. tocSelector: '.js-toc', // Where to grab the headings to build the table of contents. contentSelector: '.js-toc-content', // Which headings to grab inside of the contentSelector element. headingSelector: 'h1, h2, h3', // For headings inside relative or absolute positioned containers within content. hasInnerContainers: true, }); //点击按钮时在左侧弹出目录 $('.toc.button').popup({ popup : $('.toc-container.popup'), on : 'click', position : 'left center' }); //二维码图标 $('.addr_qrcode').popup({ popup : $('.QRcode.popup'), on : 'click', //其实默认就是hover position : 'left center' }); //根据text内容自动生成二维码 var qrcode = new QRCode("qrcode", { text: "https://silence-moon.github.io/", width: 126, height: 126, colorDark : "#000000", colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.H }); //返回顶部 $('#toTop-Btn').click(function(){ $(window).scrollTo(0,500);//grgs:(返回位置,返回过程所用时间) }); // 导航栏显示 var waypoint = new Waypoint({ element: document.getElementById('waypoint'), handler: function(direction) { if (direction == 'down') { $('#toolBar').show(500); $('#nav').show(500); } else { $('#toolBar').hide(500); } console.log('Scrolled to waypoint! ' + direction); } });</script></code></pre><h3 id="2-3-中间内容"><a href="#2-3-中间内容" class="headerlink" title="2.3 中间内容"></a>2.3 中间内容</h3><p>这里主要是分成左右两块:左侧的内容列表和右侧的卡片组<br>嗯,这里使用了animated bounceIn的动画,如果想换样式的,<br>可以去这个网站<a href="https://www.dowebok.com/demo/2014/98/" target="_blank" rel="noopener">Animate.css动画演示</a><br>看看,选择一个自己喜欢的样式。</p><pre><code class="HTML"><!-- 中间内容:animated bounceIn为显示的动画 --><div id="waypoint" class="m-container-small teal m-padding-tb-big animated bounceIn"> <div class="ui container"> <!-- 分列进行样式排版 --> <div class="ui stackable grid"> <!-- 左侧:注意这里写的时候 eleven wide column 中间不要有多余的空格或字符--> <div class="eleven wide column"> <!-- header --> <div class="ui top attached segment"> <div class="ui middle aligned two column grid"> <div class="column"> <h3 class="ui teal header">博客</h3> </div> <div class="right aligned column"> 共 <h2 class="ui orange header m-inline-blok m-text-thin"> 14 </h2> 篇 </div> </div> </div> <!-- content list --> <div class="ui attached segment"> <div class="ui padding vertical segment m-padding-tb-big"> </div> </div> <!-- footer:上一页、下一页 --> <div class="ui bottom attached segment"> <div class="ui middle aligned two column grid"> <div class="column"> <a href="#" class="ui mini teal basic button">上一页</a> </div> <div class="right aligned column"> <a href="#" class="ui mini teal basic button">下一页</a> </div> </div> </div> </div> <!-- 右侧卡片 --> <div class="five wide column"> <!-- 卡片样式:这里写2个意思一下 --> <!-- 分类卡片 --> <div class="ui segments"> <div class="ui secondary segment"> <div class="ui two column grid"> <div class="column"> <i class="idea icon"></i>分类 </div> <div class="right aligned column"> <a href="#" target="_blank">more <i class="angle double right icon"></i></a> </div> </div> </div> <div class="ui teal segment"> <!-- fluid:填充 --> <div class="ui fluid vertical menu"> <a href="#" class="item"> 学习日志 <!-- 设置数量样式 --> <div class="ui teal basic left pointing label">13</div> </a> <!-- 需要可以再行添加 --> </div> </div> </div> <!-- 标签卡片 --> <div class="ui segments m-margin-top-large"> <div class="ui secondary segment"> <div class="ui two column grid"> <div class="column"> <i class="tags icon"></i>标签 </div> <div class="right aligned column"> <a href="#" target="_blank">more <i class="angle double right icon"></i></a> </div> </div> </div> <div class="ui teal segment"> <a href="#" target="_blank" class="ui teal basic left pointing label m-margin-tb-tiny"> 方法论 <div class="detail">23</div> </a> </div> </div> </div> </div> </div></div></code></pre><p>样式如上,我进行了简化处理。</p><h2 id="三、总结"><a href="#三、总结" class="headerlink" title="三、总结"></a>三、总结</h2><p>大概的分析就如上了,具体的还是需要去实践练习的。多写两遍后感觉就没什么可讲的了。<br>其实今天再准备的时候我还特地跑到 semantic ui 这个网站上去瞅了一遍,准备做一份<br>简要的说明,写着写着,又去将这两天写的一个页面抽取出来做了一个模板,真是够乱了。<br>以后还是分享分享自己遇到的一些问题和其他内容吧,实战的过程分析真的是很麻烦啊。</p><h2 id="四、附录"><a href="#四、附录" class="headerlink" title="四、附录"></a>四、附录</h2><p>这里放上做个一个小模板,可以简单看看。<br>至于自定义的样式me.css,我把它放到我的GitHub上了,<br>可以去<a href="https://github.com/silence-moon/hsilence.github.io-blog" target="_blank" rel="noopener">前端代码地址</a>上找到对应的文件去自行下载。</p><pre><code class="HTML"><!DOCTYPE html><html> <head> <meta charset="utf-8"> <title>一个html页面的基本框架</title> <!-- 使用cnd引用semantic.min.css样式 --> <link rel="stylesheet" href="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.css"> <!-- 自定义样式 --> <link rel="stylesheet" type="text/css" href="css/me.css"/> <!-- 引入typo.css对内容进行排版 --> <link rel="stylesheet" type="text/css" href="css/typo.css"/> <!-- 引入animate.css添加动画 --> <link rel="stylesheet" type="text/css" href="css/animate.css"/> <!-- 引入prism.css实现语法高亮 --> <link rel="stylesheet" type="text/css" href="lib/prism/prism.css"/> <!-- 引入tocbot.css实现自动生成目录 --> <link rel="stylesheet" type="text/css" href="lib/tocbot/tocbot.css"/> </head> <body> <!-- 导航 --> <!-- 使用UI组件,使用inverted反转默认颜色,attached去圆角,segment表明这是一个片段,自定义上下内边距 --> <nav id="nav" class="ui inverted attached segment m-padding-tb-mini"> <div class="ui container"> <!-- 为了适应移动端,这里需要加一个属性stackable,表示可堆叠 --> <div class="ui inverted secondary stackable menu"> <!-- 添加logo,导航菜单 --> <h2 class="ui teal header item">logo</h2> <a href="index.html" class="menu-item item m-mobile-hide"><i class="home icon"></i>首页</a> <div class="right menu-item item m-mobile-hide"> <div class="ui icon input"> <input type="text" placeholder="Search..."/> <i class="search link icon"></i> </div> </div> </div> </div> <!-- 设置手机端响应时显示个菜单图标 --> <a href="#" class="ui menu toggle black icon button m-right-top m-mobile-show"> <i class="sidebar icon"></i> </a> </nav> <!-- 中间内容样式1:animated bounceIn为显示的动画 --> <div id="waypoint" class="m-container-small teal m-padding-tb-big animated bounceIn"> <div class="ui container"> <!-- 分列进行样式排版 --> <div class="ui stackable grid"> <!-- 左侧:注意这里写的时候 eleven wide column 中间不要有多余的空格或字符--> <div class="eleven wide column"> <!-- header --> <div class="ui top attached segment"> <div class="ui middle aligned two column grid"> <div class="column"> <h3 class="ui teal header">博客</h3> </div> <div class="right aligned column"> 共 <h2 class="ui orange header m-inline-blok m-text-thin"> 14 </h2> 篇 </div> </div> </div> <!-- content list --> <div class="ui attached segment"> <div class="ui padding vertical segment m-padding-tb-big"> </div> </div> <!-- footer:上一页、下一页 --> <div class="ui bottom attached segment"> <div class="ui middle aligned two column grid"> <div class="column"> <a href="#" class="ui mini teal basic button">上一页</a> </div> <div class="right aligned column"> <a href="#" class="ui mini teal basic button">下一页</a> </div> </div> </div> </div> <!-- 右侧卡片 --> <div class="five wide column"> <!-- 卡片样式:这里写2个意思一下 --> <!-- 分类卡片 --> <div class="ui segments"> <div class="ui secondary segment"> <div class="ui two column grid"> <div class="column"> <i class="idea icon"></i>分类 </div> <div class="right aligned column"> <a href="#" target="_blank">more <i class="angle double right icon"></i></a> </div> </div> </div> <div class="ui teal segment"> <!-- fluid:填充 --> <div class="ui fluid vertical menu"> <a href="#" class="item"> 学习日志 <!-- 设置数量样式 --> <div class="ui teal basic left pointing label">13</div> </a> <!-- 需要可以再行添加 --> </div> </div> </div> <!-- 标签卡片 --> <div class="ui segments m-margin-top-large"> <div class="ui secondary segment"> <div class="ui two column grid"> <div class="column"> <i class="tags icon"></i>标签 </div> <div class="right aligned column"> <a href="#" target="_blank">more <i class="angle double right icon"></i></a> </div> </div> </div> <div class="ui teal segment"> <a href="#" target="_blank" class="ui teal basic left pointing label m-margin-tb-tiny"> 方法论 <div class="detail">23</div> </a> </div> </div> </div> </div> </div> </div> <hr > <p>这里是上下2个中间内容样式的分割线</p> <hr > <!-- 中间内容样式2:animated bounceIn为显示的动画 --> <div id="" class="m-container-small teal m-padding-tb-big animated bounceIn"> <div class="ui container"> <p>使用本文件时请引用me.css样式</p> <p>同时,也需要引入本文件下的lib库</p> <h2 id="section1-3">下面看一下prism插件的代码高亮部分的显示情况:</h2> <pre><code class="language-css">p { color: red }</code></pre> <p>请先引入prism.css样式</p> <p>若要实现内容排版还请引入typo.css样式</p> </div> </div> <!-- 右侧工具栏 --> <div class=""> <!-- 目录、返回顶部等等右侧小工具 --> <div id="toolBar" class=" m-position-fixed m-position-rb" style="display: none;"> <div class="ui vertical icon buttons"> <button type="button" class="ui toc teal button">目录</button> <!-- <a href="#comment-container" class="ui teal button">留言</a> --> <button class="ui addr_qrcode icon button" title="点我生成二维码,在手机上查看"><i class="qrcode icon"></i></button> <!-- 返回顶部图标 --> <div id="toTop-Btn" class="ui button" title="返回顶部"><i class="chevron up icon" style="margin: auto !important;"></i></div> </div> </div> <!-- 目录存放位置 --> <div class="ui toc-container flowing popup transition hidden" style="width: 15.625rem !important;"> <ol class="js-toc"> </ol> </div> <!-- 二维码存放位置 --> <div id="qrcode" class="ui QRcode flowing popup transition hidden" style="width: 130px !important;"> </div> </div> <!-- 底部栏 --> <footer class="ui inverted vertical segment m-padding-tb-massive"> <div class="ui center aligned container"> <div class="ui inverted divided stackable grid"> <div class="three wide column"> <h4 class="ui inverted header">扫码关注</h4> <div class="ui inverted link list"> <div class="item"> <!-- 图片设置为圆角,并使用内联样式控制图片大小 --> <img src="img/MyBlog.png" class="ui rounded image m-div-mini" alt=""> </div> </div> </div> <div class="three wide column"> <h4 class="ui inverted header">最新博客</h4> <div class="ui inverted link list"> <a href="#" class="item">用户故事(User Story)</a> </div> </div> <div class="three wide column"> <h4 class="ui inverted header">联系我</h4> <div class="ui inverted link list"> <a href="#" class="item">Email:[email protected]</a> </div> </div> <div class="seven wide column"> <h4 class="ui inverted header">Blog</h4> <p class="m-text-thin m-text-spaced m-opacity-mini">这是我的个人博客,会分享关于编程、思考等等相关的任何内容,希望可以对来到此站的朋友有所帮助!</p> </div> </div> <div class="ui inverted section divider"></div> <p class="m-text-thin m-text-spaced m-opacity-tiny">Copyright 2020 silence Designed by silence</p> </div> </footer> <!-- cdn引入 jquery.min.js 和semantic.min.js --> <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/semantic-ui/2.2.4/semantic.min.js"></script> <!-- 引用prism.js实现代码高亮 --> <script src="lib/prism/prism.js"></script> <!-- 引用tocbot.js实现自动生成目录 --> <script src="lib/tocbot/tocbot.js"></script> <!-- 引用qrcode.js实现自动生成当前地址的二维码 --> <script src="lib/qrcode/qrcode.js"></script> <!-- 引用jquery.waypoints.min.js实现滚动侦测 --> <script src="lib/waypoints/jquery.waypoints.min.js"></script> <script> // 手机端点击menu按钮时显示菜单 $('.menu.toggle').click(function(){ // 点击按钮时检测menu-item内是否有m-mobile-hide属性,有则删除,没有则添上 $('.menu-item').toggleClass('m-mobile-hide'); }); //tocbot自动生成目录 //初始化tocbot tocbot.init({ // Where to render the table of contents. tocSelector: '.js-toc', // Where to grab the headings to build the table of contents. contentSelector: '.js-toc-content', // Which headings to grab inside of the contentSelector element. headingSelector: 'h1, h2, h3', // For headings inside relative or absolute positioned containers within content. hasInnerContainers: true, }); //点击按钮时在左侧弹出目录 $('.toc.button').popup({ popup : $('.toc-container.popup'), on : 'click', position : 'left center' }); //二维码图标 $('.addr_qrcode').popup({ popup : $('.QRcode.popup'), on : 'click', //其实默认就是hover position : 'left center' }); //根据text内容自动生成二维码 var qrcode = new QRCode("qrcode", { // text: "http://jindo.dev.naver.com/collie",http://127.0.0.1:8848/SpringBoot_blog/blog.html text: "https://silence-moon.github.io/", width: 126, height: 126, colorDark : "#000000", colorLight : "#ffffff", correctLevel : QRCode.CorrectLevel.H }); //返回顶部 $('#toTop-Btn').click(function(){ $(window).scrollTo(0,500);//grgs:(返回位置,返回过程所用时间) }); // 导航栏显示 var waypoint = new Waypoint({ element: document.getElementById('waypoint'), handler: function(direction) { if (direction == 'down') { $('#toolBar').show(500); $('#nav').show(500); } else { $('#toolBar').hide(500); // $('#nav').hide(500); } console.log('Scrolled to waypoint! ' + direction); } }); </script> </body></html></code></pre>]]></content>
<categories>
<category> 学习、开发 </category>
</categories>
<tags>
<tag> 前端开发 </tag>
<tag> 博客项目 </tag>
</tags>
</entry>
<entry>
<title>MyBlog前端开发</title>
<link href="/2020/06202291.html"/>
<url>/2020/06202291.html</url>
<content type="html"><![CDATA[<h1 id="MyBlog个人博客前端开发"><a href="#MyBlog个人博客前端开发" class="headerlink" title="MyBlog个人博客前端开发"></a>MyBlog个人博客前端开发</h1><p>作者:silence</p><p>编写日期:2020-06-20</p><p>分类:学习记录</p><p>项目演示地址:<a href="https://silence-moon.github.io/hsilence.github.io-blog/index.html">MyBlog演示地址</a></p><hr><h2 id="一、背景"><a href="#一、背景" class="headerlink" title="一、背景"></a>一、背景</h2><p>因为这几天在尝试着搭建一个自己的个人博客平台,然后逛b站的时候就看到一个讲解使用SpringBoot进行开发<br>个人博客的视频,好奇就点进去看了看,尝试了一番,接下来我就来讲一下这个项目,加深一下印象。感兴趣的也可以点击 <a href="https://www.bilibili.com/video/BV1PE411f7gS?p=20" target="_blank" rel="noopener">原视频链接</a>去b站观看。 </p><h2 id="二、项目介绍"><a href="#二、项目介绍" class="headerlink" title="二、项目介绍"></a>二、项目介绍</h2><h3 id="2-1-系统叙述"><a href="#2-1-系统叙述" class="headerlink" title="2.1 系统叙述"></a>2.1 系统叙述</h3><p>作为一个博客,首先我们要能够拥有自己的账号,而且,自己要能够在这个系统里面编写、管理、发布博客。然后,当有人对<br>我们的博客感兴趣的时候,人家要能够访问到我们的博客,并进行查看,又或者是留言。</p><h3 id="2-2-功能提取"><a href="#2-2-功能提取" class="headerlink" title="2.2 功能提取"></a>2.2 功能提取</h3><p>从2.1节的叙述中,我们可以发现,一个博客系统,至少拥有2个角色,一个是账号拥有者,或者说是管理员(当然,这里的<br>管理员只是针对自己这个账号的),还有一个就是访问者了。</p><h4 id="2-2-1-管理员功能:"><a href="#2-2-1-管理员功能:" class="headerlink" title="2.2.1 管理员功能:"></a>2.2.1 管理员功能:</h4><pre><code> - 使用用户名和密码登录,然后对博客进行管理 * 发布新博客 * 对博客进行分类 * 添加标签 * 修改博客 * 删除博客 * 根据标题、分类、标签查询博客 - 管理博客分类 * 新增 * 修改 * 删除 * 根据分类名称进行查询 - 管理博客标签 * 新增 * 修改 * 删除 * 根据名称查询标签</code></pre><h4 id="2-2-2-访问者功能:"><a href="#2-2-2-访问者功能:" class="headerlink" title="2.2.2 访问者功能:"></a>2.2.2 访问者功能:</h4><pre><code> - 可以分页查看所有的博客 - 可以快速查看博客数目最多的5个分类 - 可以查看所有分类 - 可以查看某个分类下的博客列表 - 可以快速查看标记博客最多的6个标签 - 可以查看所有标签 - 可以查看某个标签下的博客列表 - 可以根据时间线查看博客列表 - 可以快速查看最新的推荐博客 - 可以用关键字全局搜索博客 - 可以查看单个博客内容 - 可以对博客内容进行评论 - 可以赞赏博客 - 可以扫码关注</code></pre><h3 id="2-3-功能图一览"><a href="#2-3-功能图一览" class="headerlink" title="2.3 功能图一览"></a>2.3 功能图一览</h3><p>这里偷个懒,我就直接放上人家做好的功能思维导图了。<br><img src="https://img-blog.csdnimg.cn/20200621125732789.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70#pic_center" alt="在这里插入图片描述"></p><h2 id="三、前端页面开发"><a href="#三、前端页面开发" class="headerlink" title="三、前端页面开发"></a>三、前端页面开发</h2><h3 id="3-1-开发工具"><a href="#3-1-开发工具" class="headerlink" title="3.1 开发工具"></a>3.1 开发工具</h3><pre><code>- HbuildX- Semantic UI </code></pre><p><a href="https://semantic-ui.com/" target="_blank" rel="noopener">Semantic官网地址</a></p><h3 id="3-2-页面规划"><a href="#3-2-页面规划" class="headerlink" title="3.2 页面规划"></a>3.2 页面规划</h3><pre><code>- 前台展示页面:首页、详情页、分类、标签、归档、关于我- 后台管理页面:模板页</code></pre><h3 id="3-3-首页开发"><a href="#3-3-首页开发" class="headerlink" title="3.3 首页开发"></a>3.3 首页开发</h3><p>首先,我们放上一张图片,展示下成果的大体样子:<img src="https://img-blog.csdnimg.cn/20200621125732789.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70#pic_center" alt="在这里插入图片描述"></p><p>当然,由于页面大小原因,这里只能截图这么多,感兴趣的也可以去<br><a href="https://silence-moon.github.io/hsilence.github.io-blog/index.html">MyBlog演示地址</a>看看。</p><p>反正大体上也就是三块:导航、中间内容、底部</p><p>而基本上所有的代码实现都是嵌套在</p><pre><code class="HTML"><div class="ui container"></code></pre><p>这样一个div容器里面。</p><h4 id="3-3-1-导航"><a href="#3-3-1-导航" class="headerlink" title="3.3.1 导航"></a>3.3.1 导航</h4><p>导航也可以分成3个部分,即左侧logo、菜单、右侧的搜索<br>这里嵌套了三层div来做菜单,而搜索又套了一个div来实现。</p><pre><code class="HTML"><!-- 导航 --><!-- 使用UI组件,使用inverted反转默认颜色,attached去圆角,segment表明这是一个片段,自定义上下内边距 --><nav id="nav" class="ui inverted attached segment m-padding-tb-mini"> <div class="ui container"> <!-- 为了适应移动端,这里需要加一个属性stackable,表示可堆叠 --> <div class="ui inverted secondary stackable menu"> <!-- 添加logo,导航菜单 --> <h2 class="ui teal header item">Blog</h2> <a href="index.html" class="menu-item item m-mobile-hide"><i class="home icon"></i>首页</a> <a href="#" class="menu-item item m-mobile-hide"><i class="idea icon"></i>分类</a> <a href="#" class="menu-item item m-mobile-hide"><i class="tags icon"></i>标签</a> <a href="# " class="menu-item item m-mobile-hide"><i class="clone icon"></i>归档</a> <a href="#" class="menu-item item m-mobile-hide"><i class="info icon"></i>关于我</a> <div class="right menu-item item m-mobile-hide"> <div class="ui icon input"> <input type="text" placeholder="Search..."/> <i class="search link icon"></i> </div> </div> </div> </div> <!-- 设置手机端响应时显示个菜单图标 --> <a href="#" class="ui menu toggle black icon button m-right-top m-mobile-show"> <i class="sidebar icon"></i> </a></nav></code></pre><h4 id="3-3-2-中间内容"><a href="#3-3-2-中间内容" class="headerlink" title="3.3.2 中间内容"></a>3.3.2 中间内容</h4><p>中间内容从大的方面来说,可以分为左右2个部分,在下面的代码中,“文章内容部分”就是<br>左侧,而右侧卡片区域则是右侧。</p><p>就左侧区域来说,又可以分成头(博客、共**篇)、中(文章列表)、下(上一页、下一页)</p><p>中间的文章列表又可以分成左侧的文章标题、内容、右侧的图片和底部的一些信息,如头像、<br>作者、时间、浏览次数、分类等等。</p><p>右侧卡片主要有四项:分类、标签、最新推荐、扫码关注<br>其中,前三个的框架是一样的,都可以分成上下2个部分。</p><pre><code class="HTML"><!-- 中间内容 --><div class="m-container m-padding-tb-big" id="waypoint"> <div class="ui container"> <div class="ui stackable grid"> <!-- 文章内容部分 --> <div class="eleven wide column"> <!-- 头部:使用attached让上下连到一起 --> <div class="ui top attached segment"></div> <!-- 文章列表:使用attached让上下连到一起 --> <div class="ui attached segment"></div> <!-- 底部:上一页、下一页 --> <div class="ui bottom attached segment"></div> </div> <!-- 右侧卡片 --> <div class="five wide column"> <!-- 分类卡片 --> <div class="ui segments"></div> <!-- 标签卡片 --> <div class="ui segments m-margin-top-large"></div> <!-- 最新推荐卡片 --> <div class="ui segments m-margin-top-large"></div> <!-- 二维码 --> <h4 class="ui horizontal divider header m-margin-top-large">扫码关注我</h4> <!-- 设置居中格式centered,宽度为11em --> <div class="ui centered card" style="width: 11em;"> <img src="./static/images/MyBlog.png" alt="" class="ui rounded image" > </div> </div> </div> </div></div></code></pre><h4 id="3-3-3-底部栏"><a href="#3-3-3-底部栏" class="headerlink" title="3.3.3 底部栏"></a>3.3.3 底部栏</h4><p>底部栏可以分成上下2块,上侧又分成4格(注:一个grid总共有16column,可根据情况自行选择大小)<br><img src="https://img-blog.csdnimg.cn/20200621125806360.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE0Mzc4MA==,size_16,color_FFFFFF,t_70#pic_center" alt="在这里插入图片描述"></p><pre><code class="HTML"><!-- 底部栏 --><footer class="ui inverted vertical segment m-padding-tb-massive"> <div class="ui center aligned container"> <div class="ui inverted divided stackable grid"> <div class="three wide column"></div> <div class="three wide column"></div> <div class="three wide column"></div> <div class="seven wide column"> </div> <div class="ui inverted section divider"></div> <p class="m-text-thin m-text-spaced m-opacity-tiny">Copyright 2020 silence Designed by silence</p> </div></div></code></pre><h2 id="四、代码地址"><a href="#四、代码地址" class="headerlink" title="四、代码地址"></a>四、代码地址</h2><p><a href="https://github.com/silence-moon/hsilence.github.io-blog" target="_blank" rel="noopener">前端代码地址</a></p>]]></content>
<categories>
<category> 学习、开发 </category>
</categories>
<tags>
<tag> 前端开发 </tag>
<tag> 博客项目 </tag>
</tags>
</entry>
<entry>
<title>Hello World</title>
<link href="/2020/061816107.html"/>
<url>/2020/061816107.html</url>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><pre><code class="bash">$ hexo new "My New Post"</code></pre><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><pre><code class="bash">$ hexo server</code></pre><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><pre><code class="bash">$ hexo generate</code></pre><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><pre><code class="bash">$ hexo deploy</code></pre><p>More info: <a href="https://hexo.io/docs/one-command-deployment.html" target="_blank" rel="noopener">Deployment</a></p>]]></content>
</entry>
</search>