Torch 日志文件的保存 logroll
怎样将 Torch 在终端显示的信息,保存到 log 文件中 ?
现在介绍一种方法:利用 logroll 的方式。
参考 https://github.com/rosejn/logroll
1. 首先安装 logroll 工具包:
luarocks install logroll
2. 在代码头部:require "logroll" 加载该工具包:
调用的代码如下:
1 require 'paths' 2 require 'os' 3 require 'io' 4 require 'string' 5 6 require 'fn' 7 require 'pprint' 8 9 logroll = {} 10 11 local DEFAULT_LEVEL = 'INFO' 12 local LOG_LEVELS = {'DEBUG', 'INFO', 'WARN', 'ERROR'} 13 14 for i, label in ipairs(LOG_LEVELS) do 15 logroll[label] = i 16 end 17 logroll.levels = LOG_LEVELS 18 19 20 local function default_formatter(level, ...) 21 local msg = nil 22 23 if #{...} > 1 then 24 msg = string.format(({...})[1], unpack(fn.rest({...}))) 25 else 26 msg = pprint.pretty_string(({...})[1]) 27 end 28 29 return string.format("[%s - %s] - %s\n", LOG_LEVELS[level], os.date("%Y_%m_%d_%X"), msg) 30 end 31 32 33 local function default_writer(logger, level, ...) 34 if level >= logger.level then 35 logger.file:write(logger.formatter(level, unpack({...}))) 36 end 37 end 38 39 40 local function make_logger(file, options) 41 local logger = {options = options, 42 file = file, 43 formatter = options.formatter or default_formatter, 44 writer = options.writer or default_writer, 45 level = logroll[DEFAULT_LEVEL] 46 } 47 48 return fn.reduce(function(lg, level) 49 lg[string.lower(level)] = fn.partial(logger.writer, logger, logroll[level]) 50 return lg 51 end, 52 logger, LOG_LEVELS) 53 end 54 55 56 -- A simple logger to print to STDIO. 57 function logroll.print_logger(options) 58 local options = options or {} 59 return make_logger(io.stdout, options) 60 end 61 62 63 -- A logger that prints to a file. 64 function logroll.file_logger(path, options) 65 local options = options or {} 66 67 if options.file_timestamp then 68 -- append timestamp to create unique log file 69 path = path .. '-'..os.date("%Y_%m_%d_%X") 70 end 71 72 os.execute('mkdir -p "' .. paths.dirname(path) .. '"') 73 74 return make_logger(io.open(path, 'w'), options) 75 end 76 77 78 -- A logger that combines several other loggers 79 function logroll.combine(...) 80 81 local joint = { 82 subloggers = {...} 83 } 84 85 for _,level in ipairs(LOG_LEVELS) do 86 local fname = string.lower(level) 87 joint[fname] = function(...) 88 for _,lg in ipairs(joint.subloggers) do 89 lg[fname](...) 90 end 91 end 92 end 93 94 return joint 95 end
另外,也可以参考这个代码中,保存 log 文件的方式:
https://github.com/szagoruyko/cifar.torch/blob/master/train.lua#L7
1 if testLogger then
2 paths.mkdir(opt.save)
3 testLogger:add{train_acc, confusion.totalValid * 100}
4 testLogger:style{'-','-'}
5 testLogger:plot()
6
7 if paths.filep(opt.save..'/test.log.eps') then
8 local base64im
9 do
10 os.execute(('convert -density 200 %s/test.log.eps %s/test.png'):format(opt.save,opt.save))
11 os.execute(('openssl base64 -in %s/test.png -out %s/test.base64'):format(opt.save,opt.save))
12 local f = io.open(opt.save..'/test.base64')
13 if f then base64im = f:read'*all' end
14 end
15
16 local file = io.open(opt.save..'/report.html','w')
17 file:write(([[
18 <!DOCTYPE html>
19 <html>
20 <body>
21 <title>%s - %s</title>
22 <img src="data:image/png;base64,%s">
23 <h4>optimState:</h4>
24 <table>
25 ]]):format(opt.save,epoch,base64im))
26 for k,v in pairs(optimState) do
27 if torch.type(v) == 'number' then
28 file:write('<tr><td>'..k..'</td><td>'..v..'</td></tr>\n')
29 end
30 end
31 file:write'</table><pre>\n'
32 file:write(tostring(confusion)..'\n')
33 file:write(tostring(model)..'\n')
34 file:write'</pre></body></html>'
35 file:close()
36 end
37 end
其实,最简单有效粗暴的,应该是这种:
1 -- save the information into log files.
2 local logSavePath = './log_Files/'
3 local file = io.open(logSavePath..'train_record.log','a')
4 file:write(tostring("train error: " .. error)..'\n')
5 file:close()
其中,第 4 行的保存记录,也可以是其他地方的变量以及语句,等等。可以随机应变。