模型在任意未知测试样本的表现
其中 $\mathcal{G}$ 是预先给定的一个函数族, $g$ 是函数组中的一个函数, $P_{x,y}$ 是数据的真是分布,$l$ 是损失函数.
模型在训练集数据上的表现
假设有训练数据集 $S_n={(x_i,y_i),…,(x_n,y_n)}$
函数空间$\mathcal{G}$受限时,即有正则项时的表现,此时函数子空间范数小于$c$.
起因: 看到一篇文章PyCon 2018: 利用logging模块轻松地进行Python日志记录(本文也主要参考了这篇文章), 里面有几句话引起了我的注意:
- 开发过程中程序出现了问题,我们可以去debug,但是程序开发完毕,在生产环境中,我们如何追踪可能出现的问题, 这时候就需要日志记录.
- 很多人会使用 print 语句输出一些运行信息,然后再在控制台观察,这样其实是非常不规范的. (其实我就是print流的…)
不难看出logging模块的出现是为了在程序运行时输出运行时信息,有bug
时可以定位bug
,没有bug
也可以用来跟踪输出,这在追踪模型输出,评估模型好坏时也特别有用,automl
就是这个思路.
可以看出简单使用的话可以这样写:
import logging
# log级别,格式,保存位置
logging.basicConfig(
level= logging.DEBUG,
format = '%(asctime)s : %(levelname)s : %(message)s',# 运行时间,日志级别,日志内容.
filename= "test.log" #要想打印到控制台就不用这句,basicConfig下不能兼得.
)
logger = logging.getLogger(__name__)
# 下面这些写在代码里面,可以出现在任何想出现的位置.
logger.debug('debug message')
logger.info("info message")
logger.warn('warn message')
logger.error("error message")
logger.critical('critical message')
# 更加典型的使用场景,记录错误和异常.
try:
result = 10 / 0
except Exception:
logger.error('Faild to get result', exc_info=True)
logger.info('Finished')
一些解释:
asctime
,levelname
,message
分别代表运行实践,日志级别和日志信息.__name__
来代替了,就是模块的名称.2018-06-03 13:42:43,526 - __main__ - DEBUG - debug message
2018-06-03 13:42:43,526 - __main__ - INFO - debug message
2018-06-03 13:42:43,526 - __main__ - WARNING - Warning exists
2018-06-03 13:42:43,526 - __main__ - ERROR - Warning exists
2018-06-03 13:42:43,526 - __main__ - CRITICAL - Warning exists
不能做到的
所以如何更加专业地使用logging模块呢? 我们先定下几个目标,然后逐渐实现它:
现在回到问题的一开始,如何设计这样一个模块它要能完成如下任务:
粗略能想到这些,那么python
中的logging
模块是怎样实现的呢?
在 https://docs.python.org/3/library/logging.html 中有以下几个主要的对象:
具体来说Logger
用来创建一个日志记录的对象,它是所有操作的入口,Handler
和Formatter
对象最后都会传给它. 而在Logger
创建一个日志对象后, 使用Handler
来指定日志保存的位置,可以是控制台,本地文件,远程服务器,甚至是某个邮箱. 设置好保存的位置,接下来就可以定制日志的样式了,这里很重要,因为我们最终看到的日志,就是在这里设定的, 我们指定Formatter
来定制样式.
整个使用流程见下面这个图:
一个分开Logger
,Handler
,Formatter
使用的简单例子.
logging.basicConfig和logger后面再设置有什么区别.
import logging
logger = logging.getLogger(__name__) # Logger
logger.setLevel(level=logging.INFO)
handler = logging.FileHandler('output.log') # Handler
formatter = logging.Formatter\
('%(asctime)s - %(name)s - %(levelname)s - %(message)s') # Formatter
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info('This is a log info')
logger.debug('Debugging')
logger.warning('Warning exists')
logger.info('Finish')
结合上面的流程图和上面代码中的这两行:
handler.setFormatter(formatter)
logger.addHandler(handler)
可以看出Formatter
传给Handler
,Handler
带着自身和Formatter
的信息又传给了Logger
, 最后完成了一个完整的日志记录过程.
那么我们来一个一个分析Formatter
,Handler
,Logger
.
Logger
一般不会单独使用,而是使用模块级别的函数logging.getLogger(name)
,常用的记录器对象的方法分为两类:配置和发送消息。
Logger.setLevel()
Logger.debug()
….
日志级别如下:Level | Numeric value |
---|---|
CRITICAL | 50 |
ERROR | 40 |
WARNING | 30 |
INFO 2 | 0 |
DEBUG | 10 |
NOTSET | 0 |
还有一些方法如:
import logging
from logging.handlers import HTTPHandler
import sys
logger = logging.getLogger(__name__)
logger.setLevel(level=logging.DEBUG)
# StreamHandler
stream_handler = logging.StreamHandler(sys.stdout)
stream_handler.setLevel(level=logging.DEBUG)
logger.addHandler(stream_handler)
# FileHandler
file_handler = logging.FileHandler('output.log')
file_handler.setLevel(level=logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
# HTTPHandler
http_handler = HTTPHandler(host='localhost:8001', url='log', method='POST')
logger.addHandler(http_handler)
# SMTPHandler
smtp_handler=SMTPHandler(mailhost=("smtp.163.com", 25), fromaddr='sunqiang42@163.com',
toaddrs=['sq11235@163.com',],
subject="logging to email test",
credentials=('sunqiang42@163.com', '***'),
)
logger.addHandler(smtp_handler)
# Log
logger.info('This is a log info')
logger.debug('Debugging')
logger.warning('Warning exists')
logger.info('Finish')
上述代码在运行后会在:
这里我们就完成了几个任务:
Formatter和前面基本语句差不多,不在赘述.
我们希望在一个地方定义好了logging配置,然后在别的模块里复用就行了.比如说在main.py
函数里定义好了level,formatter,handler等信息,然后如果main.py
中调用别的模块,在该模块里面也能使用main.py
中的logger配置.
# main.py
import logging
import core
logger = logging.getLogger('main')
logger.setLevel(level=logging.DEBUG)
# Handler
handler = logging.FileHandler('result.log')
handler.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.info('Main Info')
logger.debug('Main Debug')
logger.error('Main Error')
core.run()# main中可能要调用core的信息
这就设置好了模板.然后在core中:
# core.py
import logging
logger = logging.getLogger('main.core')# 在core.py的开头只需要写上这两句就可以了.
def run():
logger.info('Core Info')
logger.debug('Core Debug')
logger.error('Core Error')
把配置写到日志配置文件中去:(有.conf和.yaml多种方式,看起来还是.yaml更加直观.)
# logging.yaml
formatters:
brief:
format: "%(asctime)s - %(message)s"
simple:
format: "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
handlers:
console:
class : logging.StreamHandler
formatter: brief
level : INFO
stream : ext://sys.stdout
file:
class : logging.FileHandler
formatter: simple
level: DEBUG
filename: debug.log
error:
class: logging.handlers.RotatingFileHandler
level: ERROR
formatter: simple
filename: error.log
maxBytes: 10485760
backupCount: 20
encoding: utf8
loggers:
main.core:
level: DEBUG
handlers: [console, file, error]
root:
level: DEBUG
handlers: [console]
然后在程序中调用
import logging
import logging.config
logging.config.fileConfig('logging.conf')
logger = logging.getLogger(__name__)
logger.debug('debug message')
logger.info("info message")
logger.warn('warn message')
logger.error("error message")
logger.critical('critical message')
可以看出日志的配置更加灵活,几句话概括就是不同的handler可以使用不同的formmter,不同的 logger可以使用不同的handler.
然后我们可以这样使用:
# main_conf.py
import logging
import core
import yaml
import logging.config
import os
def setup_logging(default_path='config.yaml', default_level=logging.INFO):
path = default_path
if os.path.exists(path):
with open(path, 'r', encoding='utf-8') as f:
config = yaml.load(f)
logging.config.dictConfig(config)
else:
logging.basicConfig(level=default_level)
def log():
logging.debug('Start')
logging.info('Exec')
logging.info('Finished')
if __name__ == '__main__':
yaml_path = 'config.yaml'
setup_logging(yaml_path)
log()
core.run()
https://github.com/Delgan/loguru
未完待续!
参考资料:
论文发表流程:
确定方向 | 统计机器翻译 |
---|---|
确定问题 | 利用句法对长距离调序建模 |
确定思路 | 将树到串对泛化为树到串模板 |
确定方法 | 规则抽取,抽取算法 |
实验验证 | 数据集、基线系统、评价指标 |
撰写论文 | 投稿ACL |
<龙星计划>邢波老师致广大学员一封信(2010-10-26)
http://bcmi.sjtu.edu.cn/ds/
亲爱的同学们,很荣幸这五天能和大家在龙星计划课堂和大家相识。我真诚地希望你们能够带着耐心和热情学完所有的章节,我也非常高兴你们能享受到这些课程的乐趣。作为一个老师你们的赞同和支持是对我最高的褒奖。我收到许多你们关于如何做一个好的研究者的问题,下面我分享一下我几年前也给一个同学类似的建议,这个同学名字我已经忘了。希望这些建议作为李菲菲关于如何做一个好的研究者的补充。
最后我祝愿你们在即将到来的一年快乐、丰收。
eric
准备:
为什么要使用jekyll,jekyll的中文网站已经解释的很清楚了:
简单 不再需要数据库,不需要开发评论功能,不需要不断的更新版本——只用关心你的博客内容。 使用 Jekyll
静态 Markdown(或 Textile)、Liquid 和 HTML & CSS 构建可发布的静态网站。 Jekyll 模版
博客支持 支持自定义地址、博客分类、页面、文章以及自定义的布局设计。 迁移你的博客
建议在linux系统下使用jekyll, 我在windows下折腾了半天都没能解决编码问题,官方也告诫最好不要在windows下使用,如果手里只有windows计算机,可以使用win10自带的ubuntu子系统,亲测有效.
apt-get install ruby-full
然后到ruby中国去替换ruby源,不然安装包会很慢.
gem sources --add https://gems.ruby-china.com/ --remove https://rubygems.org/
bundle config mirror.https://rubygems.org https://gems.ruby-china.com
gem
安装jekyll
gem install jekyll
先从简单的开始,克隆一个项目:
$git clone https://github.com/poole/poole.git
$cd pool
$jekyll serve
Configuration file: /mnt/d/code/learbhub/blog/poole/_config.yml
Deprecation: The 'gems' configuration option has been renamed to 'plugins'. Please update your config file accordingly.
Source: /mnt/d/code/learbhub/blog/poole
Destination: /mnt/d/code/learbhub/blog/poole/_site
Incremental build: disabled. Enable with --incremental
Generating...
done in 1.388 seconds.
Auto-regeneration may not work on some Windows versions.
Please see: https://github.com/Microsoft/BashOnWindows/issues/216
If it does not work, please upgrade Bash on Windows or run Jekyll with --no-watch.
Auto-regeneration: enabled for '/mnt/d/code/learbhub/blog/poole'
Server address: http://127.0.0.1:4000/
Server running... press ctrl-c to stop.
这时在本地(http://127.0.0.1:4000/)就可以打开访问了
远端访问可以使用命令:
jekyll s --host='0.0.0.0'
主要模块及其作用:
_config.yml
保存配置数据。很多配置选项都可以直接在命令行中进行设置,但是如果你把那些配置写在这儿,你就不用非要去记住那些命令了。_drafts
drafts(草稿)是未发布的文章。这些文件的格式中都没有 title.MARKUP 数据。_includes
你可以加载这些包含部分到你的布局或者文章中以方便重用。可以用这个标签 来把文件 _includes/file.ext 包含进来。_layouts
layouts(布局)是包裹在文章外部的模板。布局可以在 YAML 头信息中根据不同文章进行选择。_posts
这里放的就是你的文章了。文件格式很重要,必须要符合: YEAR-MONTH-DAY-title.MARKUP。_data
格式化好的网站数据应放在这里。jekyll 的引擎会自动加载在该目录下所有的 yaml 文件(后缀是 .yml, .yaml, .json 或者 .csv )。这些文件可以经由 `site.data` 访问。如果有一个 members.yml 文件在该目录下,你就可以通过 site.data.members 获取该文件的内容。_site
一旦 Jekyll 完成转换,就会将生成的页面放在这里(默认)。最好将这个目录放进你的 .gitignore 文件中。index.html and other HTML, Markdown, Textile files
如果这些文件中包含 YAML 头信息 部分,Jekyll 就会自动将它们进行转换。当然,其他的如 .html, .markdown, .md, 或者 .textile 等在你的站点根目录下或者不是以上提到的目录中的文件也会被转换。其他
其他一些未被提及的目录和文件如 css 还有 images 文件夹, favicon.ico 等文件都将被完全拷贝到生成的 site 中pool里面的目录结构是这样的:
poole/
├── 404.html
├── LICENSE.md
├── README.md
├── _config.yml
├── _includes # 方便文件重用
│ └── head.html
├── _layouts # 外部的模板,控制页面样式
│ ├── default.html
│ ├── page.html
│ └── post.html
├── _posts # 存放文章的地方,一般都是markdown文件
│ ├── 2016-01-01-whats-jekyll.md
│ ├── 2016-01-02-example-content.md
│ └── 2016-01-03-introduction.md
├── _sass # css扩展,控制样式
│ ├── _base.scss
│ ├── _code.scss
│ ├── _layout.scss
│ ├── _masthead.scss
│ ├── _message.scss
│ ├── _pagination.scss
│ ├── _posts.scss
│ ├── _syntax.scss
│ ├── _type.scss
│ └── _variables.scss
├── _site # jekyll转化后的文件
│ ├── 2016
│ │ └── 01
│ │ ├── 01
│ │ │ └── whats-jekyll
│ │ │ └── index.html
│ │ ├── 02
│ │ │ └── example-content
│ │ │ └── index.html
│ │ └── 03
│ │ └── introduction
│ │ └── index.html
│ ├── 404.html
│ ├── LICENSE.md
│ ├── README.md
│ ├── about
│ │ └── index.html
│ ├── atom.xml
│ ├── index.html
│ ├── page2
│ │ └── index.html
│ ├── page3
│ │ └── index.html
│ ├── public
│ │ ├── apple-touch-icon-precomposed.png
│ │ └── favicon.ico
│ └── styles.css
├── about.md # 简介
├── atom.xml
├── index.html # 首页
├── public # 公共文件
│ ├── apple-touch-icon-precomposed.png
│ └── favicon.ico
└── styles.scss
18 directories, 41 files
_posts
存放markdwon
文件的地方_config.yml
配置_posts
所有的文章直接放在_posts文件夹下面,格式就是我们之前提到的markdown文件,默认的格式是.md和.markdown文件。每篇文章的开始处需要使用yml格式来写明这篇文章的简单介绍,格式如下:
---
author: kresnikwang
comments: true # 是否能被评论
date: 2015-04-28 17:42:32+00:00
layout: post
title: PHP, Angular JS Development|My Export Quote|农产品出口工具开发
categories: # 分类
- Works
- Tech
tags: # 标签
- bootstrap
- javascript
- php
- AngularJS
---
_config.yml
详见(http://jekyllcn.com/docs/configuration/)
# Permalinks
permalink: pretty
# Setup
title: Poole
tagline: The Jekyll Butler
url: http://getpoole.com
paginate: 1
baseurl: ""
# Assets
#
# We specify the directory for Jekyll so we can use @imports.
sass:
sass_dir: _sass
style: :compressed
# About/contact
author:
name: Mark Otto
url: https://twitter.com/mdo
email: markdotto@gmail.com
# Custom vars
version: 2.0.0
github:
repo: https://github.com/poole/poole
# Gems
gems:
- jekyll-paginate
- jekyll-gist