我们正在开源Lore框架,这个框架可供机器学习研究人员使用。
Lore地址:https://github.com/instacart/lore
机器学习常常给人一种这样的感觉:
论文没有告诉我该如何工作......
常见问题
为了解决这些问题,我们将Lore中的机器学习标准化。在Instacart,我们三个团队使用Lore进行所有新的机器学习开发,目前我们正在运行十几种Lore模型。
如果你想要一个超级快速的在没有上下文的情况下进行预测的演示服务,你可以从github复制can my_app
。如果你想要了解整个过程,请跳至概要(即15分钟概要)。
ip3 install lore
$ git clone https://github.com/montanalow/my_app.git
$ cd my_app
$ lore install # caching all dependencies locally takes a few minutes the first time
$ lore server &
$ curl "http://localhost:5000/product_popularity.Keras/predict.json?product_name=Banana&department=produce"
了解这些优势的最好方法是在15分钟内将自己的深度学习项目投入生产。如果你想在查看终端与开始编写代码之前查看特征参数,请阅读以下简要概述:
基本的python知识是必需的。如果你的机器拒绝学习,你可以在接下来的一年里探索错综复杂的机器学习。
# On Linux
$ pip install lore
# On OS X use homebrew python 2 or 3
$ brew install python3 && pip3 install lore
runtime.txt
和 requirements.txt
的指定版本中。 这使得分享Lore应用程序的效率更高,并使我们向机器学习项目迈进了一步。--keras
来安装此项目的深度学习依赖项。$ lore init my_app --python-version=3.6.4 --keras
$ cd my_app
$ lore generate scaffold product_popularity --keras --regression --holdout
每个lore模型都包含一个用来装载和编码数据的Pipeline,以及实现特定机器学习算法的估计器。模型中有趣的部分是生成类的实现细节。
Pipeline从左侧的原始数据开始,并将其编码到右边的期望型式中。然后使用编码的数据对估计器进行训练,在验证集中进行早期停止,并在测试集上进行评估。所有的东西都可以序列化到模型存储中,然后再加载一个liner进行部署。
通过它的生命周期剖析一个模型
lore.pipelines
中的基本类别将此逻辑封装在标准工作流程中。lore.pipelines.holdout.Base
将我们的数据分割成训练,验证和测试集,并对我们的机器学习算法进行编码。我们的子类将负责定义3个方法: methods: get_data
, get_encoders
, 和 get_output_encoder
。get_data
将下载原始Instacart数据,并使用pandas将其加入到具有以总单位为特征(product_name, department)和响应(sales)的DataFrame中,例如:get_data的实现
:# my_app/pipelines/product_popularity.py part 1
import os
from lore.encoders import Token, Unique, Norm
import lore.io
import lore.pipelines
import lore.env
import pandas
class Holdout(lore.pipelines.holdout.Base):
# You can inspect the source data csv's yourself from the command line with:
# $ wget https://s3.amazonaws.com/instacart-datasets/instacart_online_grocery_shopping_2017_05_01.tar.gz
# $ tar -xzvf instacart_online_grocery_shopping_2017_05_01.tar.gz
def get_data(self):
url = 'https://s3.amazonaws.com/instacart-datasets/instacart_online_grocery_shopping_2017_05_01.tar.gz'
# Lore will extract and cache files in lore.env.data_dir by default
lore.io.download(url, cache=True, extract=True)
# Defined to DRY up paths to 3rd party file hierarchy
def read_csv(name):
path = os.path.join(
lore.env.data_dir,
'instacart_2017_05_01',
name + '.csv')
return pandas.read_csv(path, encoding='utf8')
# Published order data was split into irrelevant prior/train
# sets, so we will combine them to re-purpose all the data.
orders = read_csv('order_products__prior')
orders = orders.append(read_csv('order_products__train'))
# count how many times each product_id was ordered
data = orders.groupby('product_id').size().to_frame('sales')
# add product names and department ids to ordered product ids
products = read_csv('products').set_index('product_id')
data = data.join(products)
# add department names to the department ids
departments = read_csv('departments').set_index('department_id')
data = data.set_index('department_id').join(departments)
# Only return the columns we need for training
data = data.reset_index()
return data[['product_name', 'department', 'sales']]
# my_app/pipelines/product_popularity.py part 2
def get_encoders(self):
return (
# An encoder to tokenize product names into max 15 tokens that
# occur in the corpus at least 10 times. We also want the
# estimator to spend 5x as many resources on name vs department
# since there are so many more words in english than there are
# grocery store departments.
Token('product_name', sequence_length=15, minimum_occurrences=10, embed_scale=5),
# An encoder to translate department names into unique
# identifiers that occur at least 50 times
Unique('department', minimum_occurrences=50)
)
def get_output_encoder(self):
# Sales is floating point which we could Pass encode directly to the
# estimator, but Norm will bring it to small values around 0,
# which are more amenable to deep learning.
return Norm('sales')
lore.estimators.keras.Regression
的一个简单的子类,它实现一个值典型的带有合理默认的深度学习架构。# my_app/estimators/product_popularity.py
import lore.estimators.keras
class Keras(lore.estimators.keras.Regression):
pass
# my_app/models/product_popularity.py
import lore.models.keras
import my_app.pipelines.product_popularity
import my_app.estimators.product_popularity
class Keras(lore.models.keras.Base):
def __init__(self, pipeline=None, estimator=None):
super(Keras, self).__init__(
my_app.pipelines.product_popularity.Holdout(),
my_app.estimators.product_popularity.Keras(
hidden_layers=2,
embed_size=4,
hidden_width=256,
batch_size=1024,
sequence_embedding='lstm',
)
)
当你生成过渡支架时,会自动为该模型创建一个烟雾测试。第一次运行需要一些时间来下载200MB的测试数据集。一个好的做法是减少./tests/data中的
缓存的文件,并在你的repo中检查它们,以删除网络依赖项并加速测试运行。
$ lore test tests.unit.test_product_popularity
训练一个模型将在./data中缓存数据,并在 ./models中保存文件
。
$ lore fit my_app.models.product_popularity.Keras --test --score
$ tail -f logs/development.log
score
。你可以编辑模型文件,或者通过命令行调用来直接传递属性,例如: --hidden_layers=5
。使用缓存的数据集大约需要30秒。你可以在lore环境中运行jupyter notebooks。Lore将会安装一个定制的jupyter内核,它将会为你的lore notebook
和lore console
,引用你的应用程序的虚拟环境。
$ lore notebook
notebooks/product_popularity/features.ipynb
并且“运行所有”可以看到模型最后一个拟合的一些可视化效果。“生产”部门编码为“20”
你可以看到模型的预测(蓝色)是如何跟踪测试集(金色)的,并对特定的特征进行聚合。在这种情况下,有21个部门有相当好的重叠,除了“生产”,模型没有完全解释异常值是多少。
你还可以看到笔记本电脑上运行笔记本产生的深度学习架构notebooks/product_popularity/architecture.ipynb。
媒体不支持svg,所以这是不可读的,但notebooks可以
在左边的LSTM中,有15个标记化的部分,而department name被输入到右侧的嵌入中,然后通过隐藏的层。
Lore应用程序可以作为一个HTTP API在本地运行。默认情况下,模型将通过HTTP GET端点公开他们的“预测”方法。
$ lore server &
$ curl "http://localhost:5000/product_popularity.Keras/predict.json?product_name=Banana&department=produce"
$ curl "http://localhost:5000/product_popularity.Keras/predict.json?product_name=Organic%20Banana&department=produce"
$ curl "http://localhost:5000/product_popularity.Keras/predict.json?product_name=Green%20Banana&department=produce"
$ curl "http://localhost:5000/product_popularity.Keras/predict.json?product_name=Brown%20Banana&department=produce"
./models/my_app.models.product_popularity/Keras/
中发布lore fit
命令的结果。该目录和./data/默认位于.gitignore中,因为你的代码始终可以重新创建它们。一个简单的部署策略是检查将要发布的模型版本。$ git init .
$ git add .
$ git add -f models/my_app.models.product_popularity/Keras/1 # or your preferred fitting number to deploy
$ git commit -m "My first lore app!"
$ heroku login
$ heroku create
$ heroku config:set LORE_PROJECT=my_app
$ heroku config:set LORE_ENV=production
$ git push heroku master
$ heroku open
$ curl “`heroku info -s | grep web_url | cut -d= -f2`product_popularity.Keras/predict.json?product_name=Banana&department=produce”
现在你可以用你的heroku应用程序名称替换http://localhost:5000/,然后你可以从任何地方访问你的预测!
*或者,你可以和我的heroku应用互动。
我们认为0.5版本是与社区一起构建为1.0的坚实基础。修补程序版本将避免重大更改,但次要版本可能会根据社区需求更改功能。我们将弃用并发布警告,以保持现有应用程序的清晰升级路径。
下面是我们想在1.0之前添加的一些特性: