专栏名称: 人工智能头条
专注人工智能技术前沿、实战技巧及大牛心得。
目录
相关文章推荐
黄建同学  ·  LeRobot都能接大模型了↓-202506 ... ·  昨天  
机器之心  ·  挑战 next token ... ·  2 天前  
爱可可-爱生活  ·  【Anthropic团队内部如何用Claud ... ·  3 天前  
爱可可-爱生活  ·  #听见微博# #微博声浪计划# ... ·  3 天前  
爱可可-爱生活  ·  人人能懂的AI前沿解读(6.7)网页链接 ... ·  3 天前  
51好读  ›  专栏  ›  人工智能头条

机器学习如何从Python 2迁移到Python 3

人工智能头条  · 公众号  · AI  · 2018-01-29 20:40

正文

请到「今天看啥」查看全文


frequency ( speed : u.meter / u.s, wavelength : u.m) -> u.terahertz:
return speed / wavelength     frequency( speed = 300_000 * u.km / u.s, wavelength = 555 * u.nm)
# output: 540.5405405405404 THz, frequency of green visible light


如果你需要用Python处理表格类型的科学数据,你可以尝试astropy包,体验一下计量单位随意转换的方便性。你还可以针对某个应用专门定义一个装饰器,用同样的方式来控制或转换输入和输出的计量单位。


通过 @ 实现矩阵乘法


下面,我们实现一个最简单的机器学习模型,即带 L2 正则化的线性回归 (如岭回归模型),来对比 Python2 和 Python3 之间的差别:


# l2-regularized linear regression: || AX - b ||^2 + alpha * ||x||^2 -> min

#
Python 2
X
= np.linalg.inv(np.dot(A.T, A) + alpha * np.eye(A.shape[1])).dot(A.T.dot(b))
# Python 3
X
= np.linalg.inv(A.T @ A + alpha * np.eye(A.shape[1])) @ (A.T @ b)


在 Python3 中,以@作为矩阵乘法符号使得代码整体的可读性更强,且更容易在不同的深度学习框架间进行转译:因为一些代码如 X @ W + b[None, :] 在 numpy、cupy、pytorch 和 tensorflow 等不同库中都表示单层感知机。


使用 ** 作为通配符


Python2 中使用递归文件夹的通配符并不是很方便,因此可以通过定制的 glob2 模块来解决这个问题。递归 flag 在 Python 3.6 中得到了支持。


import glob

#
Python 2
found_images
= \
   glob.glob('/path/*.jpg') \
 + glob.glob('/path/*/*.jpg') \
 + glob.glob('/path/*/*/*.jpg') \
 + glob.glob('/path/*/*/*/*.jpg') \
 + glob.glob('/path/*/*/*/*/*.jpg') # Python 3
found_images
= glob.glob('/path/**/*.jpg', recursive=True)


Python3 中更好的选择是使用 pathlib:(缺少个import)


# Python 3found_images = pathlib.Path('/path/').glob('**/*.jpg')


Python3中的print函数


诚然,print 在 Python3 中是一个函数,使用 print 需要加上圆括弧(),虽然这是个麻烦的操作,但它还是具有一些优点:


  • 使用文件描述符的简单句法:


print >>sys.stderr, "critical error"      # Python 2
print("critical error", file=sys.stderr)  # Python 3


  • 在不使用str.join情况下能够输出 tab-aligned 表格:



# Python 3
print(*array, sep='\t')
print(batch, epoch, loss, accuracy, time, sep='\t')


  • 修改与重新定义 print 函数的输出:



# Python 3
_print
= print # store the original print function
def print(*args, **kargs):
   pass  # do something useful, e.g. store output to some file


在 Jupyter notebook 中,这种形式能够记录每一个独立的文档输出,并在出现错误的时候追踪到报错的文档。这能方便我们快速定位并解决错误信息。因此我们可以重写 print 函数。


在下面的代码中,我们可以使用上下文管理器来重写 print 函数的行为:


@contextlib.contextmanager
def replace_print():
   import builtins    _print = print # saving old print function    # or use some other function here    builtins.print = lambda *args, **kwargs: _print('new printing', *args, **kwargs)    yield    builtins.print = _print
   
with replace_print():
   <code here will invoke other
print function>


但是,重写print函数的行为,我们并不推荐,因为它会引起系统的不稳定。


  • print函数可以结合列表生成器或其它语言结构一起使用。



# Python 3
result
= process(x) if is_valid(x) else print('invalid item: ', x)


f-strings 可作为简单和可靠的格式化


默认的格式化系统提供了一些灵活性操作。但在数据实验中这些操作不仅不是必须的,还会导致代码的修改变得冗长和琐碎。


而数据科学通常需要以固定的格式,迭代地打印出一些日志信息,所使用的代码如下:


# Python 2
print('{batch:3} {epoch:3} / {total_epochs:3}  accuracy: {acc_mean:0.4f}±{acc_std:0.4f} time: {avg_time:3.2f}'.format(
   batch=batch, epoch=epoch, total_epochs=total_epochs,    acc_mean=numpy.mean(accuracies), acc_std=numpy.std(accuracies),
   avg_time=time / len(data_batch) ))






请到「今天看啥」查看全文