SlideShare ist ein Scribd-Unternehmen logo
1 von 79
Tools for Making
Machine Learning
more Reactive
Jeff Smith
@jeffksmithjr
jeffsmith.tech
Reactive Machine Learning
Background Survey
Reactive Systems
Reactive Strategies
Machine Learning Systems
Reactive Machine Learning
Reactive at Intent Media
Language Survey
Languages
● Scala
● Erlang/Elixir
● Python
Responding
Agriculture
Akka
● Scala & Java
● Actor model
● Concurrency
● Distribution
● Supervision
Model Microservices
Model Microservice in Akka HTTP
case class Prediction(id: Long, timestamp: Long, value: Double)
trait Protocols extends DefaultJsonProtocol {
implicit val predictionFormat = jsonFormat3(Prediction)
}
Model Microservice in Akka HTTP
def model(features: Map[Char, Double]) = {
val coefficients = ('a' to 'z').zip(1 to 26).toMap
val predictionValue = features.map {
case (identifier, value) =>
coefficients.getOrElse(identifier, 0) * value
}.sum / features.size
Prediction(Random.nextLong(), System.currentTimeMillis(), predictionValue)
}
def parseFeatures(features: String): Map[String, Double] = {
features.parseJson.convertTo[Map[Char, Double]]
}
def predict(features: String): Prediction = {
model(parseFeatures(features))
}
Model Microservice in Akka HTTP
trait Service extends Protocols {
implicit val system: ActorSystem
implicit def executor: ExecutionContextExecutor
implicit val materializer: Materializer
val logger: LoggingAdapter
val routes = {
logRequestResult("model-service") {
pathPrefix("predict") {
(get & path(Segment)) {
features: String =>
complete {
ToResponseMarshallable(predict(features))}}}}}}
Model Serialization
Random Forest in Spark MLlib
MLlib Model Serialization
{
"class": "org.apache.spark.ml.PipelineModel",
"timestamp": 1467653845388,
"sparkVersion": "2.0.0-preview",
"uid": "pipeline_6b4fb08e8fb0",
"paramMap": {
"stageUids": ["quantileDiscretizer_d3996173db25",
"vecAssembler_2bdcd79fe1cf",
"logreg_9d559ca7e208"]
}
}
MLlib Model Serialization
{ "class": "org.apache.spark.ml.classification.LogisticRegressionModel",
"timestamp": 1467653845650,
"sparkVersion": "2.0.0-preview",
"uid": "logreg_9d559ca7e208",
"paramMap": {
"threshold": 0.5,
"elasticNetParam": 0.0,
"fitIntercept": true,
"tol": 1.0E-6,
"regParam": 0.0,
"maxIter": 5,
"standardization": true,
"featuresCol": "features",
"rawPredictionCol": "rawPrediction",
"predictionCol": "prediction",
"probabilityCol": "probability",
"labelCol": "label"}}
Parquet
Packaging
Containerizing with sbt-docker
dockerfile in docker := {
val jarFile: File = sbt.Keys.`package`.in(Compile, packageBin).value
val classpath = (managedClasspath in Compile).value
val mainClass = "com.reactivemachinelearning.PredictiveService"
val jarTarget = s"/app/${jarFile.getName}"
val classpathString = classpath.files.map("/app/" + _.getName)
.mkString(":") + ":" + jarTarget
new Dockerfile {
from("java")
add(classpath.files, "/app/")
add(jarFile, jarTarget)
entryPoint("java", "-cp", classpathString, mainClass)
}
}
Containerizing with sbt-docker
FROM java
ADD 0/spark-core_2.11-2.0.0-preview.jar 1/avro-mapred-1.7.7-hadoop2.jar ...
ADD 166/chapter-7_2.11-1.0.jar /app/chapter-7_2.11-1.0.jar
ENTRYPOINT ["java", "-cp", "/app/spark-core_2.11-2.0.0-preview.jar ...
"com.reactivemachinelearning.PredictiveService"]
Model Servers
Transportation
Model Server in http4s
object Models {
val modelA = HttpService {
case GET -> Root / "a" / inputData =>
val response = true
Ok(s"Model A predicted $response.")
}
val modelB = HttpService {
case GET -> Root / "b" / inputData =>
val response = false
Ok(s"Model B predicted $response.")
}
}
Model Server in http4s
object Client {
val client = PooledHttp1Client()
private def call(model: String, input: String) = {
val target = Uri.fromString(s"http://localhost:8080/models/$model/$input").toOption.get
client.expect[String](target)
}
def callA(input: String) = call("a", input)
def callB(input: String) = call("b", input)
}
Model Server in http4s
def splitTraffic(data: String) = {
data.hashCode % 10 match {
case x if x < 4 => Client.callA(data)
case _ => Client.callB(data)
}
}
Model Server in http4s
object ModelServer extends ServerApp {
val apiService = HttpService {
case GET -> Root / "predict" / inputData =>
val response = splitTraffic(inputData).run
Ok(response)
}
override def server(args: List[String]): Task[Server] = {
BlazeBuilder
.bindLocal(8080)
.mountService(apiService, "/api")
.mountService(Models.modelA, "/models")
.mountService(Models.modelB, "/models")
.start
}
}
Model Server in http4s
import scala.util.Random
val modelC = HttpService {
case GET -> Root / "c" / inputData => {
val workingOk = Random.nextBoolean()
val response = true
if (workingOk) {
Ok(s"Model C predicted $response.")
} else {
BadRequest("Model C failed to predict.")
}
}
}
Model Server in http4s
private def call(model: String, input: String): Task[Response] = {
val target = Uri.fromString(
s"http://localhost:8080/models/$model/$input"
).toOption.get
client(target)
}
def callC(input: String) = call("c", input)
Model Server in http4s
def splitTraffic(data: String) = {
data.hashCode % 10 match {
case x if x < 4 => Client.callA(data)
case x if x < 6 => Client.callB(data)
case _ => Client.callC(data)
}
}
val apiService = HttpService {
case GET -> Root / "predict" / inputData =>
val response = splitTraffic(inputData).run
response match {
case r: Response if r.status == Ok => Response(Ok).withBody(r.bodyAsText)
case r => Response(BadRequest).withBody(r.bodyAsText)
}
}
Model Server in http4s
def splitTraffic(data: String) = {
data.hashCode % 10 match {
case x if x < 4 => Client.callA(data)
case x if x < 6 => Client.callB(data)
case _ => Client.callC(data)
}
}
val apiService = HttpService {
case GET -> Root / "predict" / inputData =>
val response = splitTraffic(inputData).run
response match {
case r: Response if r.status == Ok => Response(Ok).withBody(r.bodyAsText)
case r => Response(BadRequest).withBody(r.bodyAsText)
}
}
Model Server in http4s
private def call(model: String, input: String) = {
val target = Uri.fromString(s"http://localhost:8080/models/$model/$input").toOption.get
client(target).retry(Seq(1 second), {_ => true})
}
BEAM
Erlang
Elixir
Knowledge Maintenance
Circuit Breakers in Erlang/Elixir
def update(user_data) do
{user_id, _} = user_data
case verify_fuse(user_id) do
:ok ->
write_to_db(user_data)
|> parse_db_response(user_id)
:sorry ->
IO.puts "This user can't be updated now. ¯_(ツ)_/¯"
:sorry
end
end
Circuit Breakers in Erlang/Elixir
defp verify_fuse(user_id) do
case :fuse.ask(user_id, :sync) do
{:error, :not_found} ->
IO.puts "Installing"
install_fuse(user_id)
:ok
:blown ->
:sorry
_ -> :ok
end
end
Circuit Breakers in Erlang/Elixir
defp install_fuse(user_id) do
:fuse.install(user_id, {{:standard, 3, 60000}, {:reset, 900000}})
end
Circuit Breakers in Erlang/Elixir
defp write_to_db({_user_id, _data}) do
Enum.random([{:ok, ""}, {:error, "The DB dropped the ball. ಠ_ಠ"}])
end
Circuit Breakers in Erlang/Elixir
defp parse_db_response({:ok, _}, _user_id) do
:ok
end
defp parse_db_response({:error, message}, user_id) do
:fuse.melt(user_id)
IO.puts "Error encountered: #{message}.nMelting the fuse!"
:sorry
end
Circuit Breakers in Erlang/Elixir
def update(user_data) do
{user_id, _} = user_data
case verify_fuse(user_id) do
:ok ->
write_to_db(user_data)
|> parse_db_response(user_id)
:sorry ->
IO.puts "This user can't be updated now. ¯_(ツ)_/¯"
:sorry
end
end
Circuit Breakers in Akka
class DangerousActor extends Actor with ActorLogging {
import context.dispatcher
val breaker =
new CircuitBreaker(
context.system.scheduler,
maxFailures = 5,
callTimeout = 10.seconds,
resetTimeout = 1.minute).onOpen(notifyMeOnOpen())
def notifyMeOnOpen(): Unit =
log.warning("My CircuitBreaker is now open, and will not close for one minute")
}
Circuit Breakers in Lagom
def descriptor: Descriptor = {
import Service._
named("hello").withCalls(
namedCall("hi", this.sayHi),
namedCall("hiAgain", this.hiAgain)
.withCircuitBreaker(CircuitBreaker.identifiedBy("hello2"))
)
}
Deep Learning
Python
Galápagos Nǎo
Diversity in Ecosystems
Evolution
def evolve(nets, generations) do
evolve(nets, generations, &decrement/1)
end
def evolve(nets, generations, count_function) when generations > 0 do
Task.Supervisor.async(GN.TaskSupervisor, fn ->
IO.puts("Generations remaining: #{generations}")
learn_generation(nets)
|> select()
|> evolve(count_function.(generations), count_function)
end)
end
def evolve(nets, _generations, _count_function) do
nets
end
Evolution
def learn_generation(nets) do
clean_nets = strip_empties(nets)
tasks =
Task.Supervisor.async_stream_nolink(
GN.TaskSupervisor,
clean_nets,
&start_and_spawn(&1),
timeout: GN.Parameters.get(__MODULE__, :timeout)
)
generation = for {status, net} <- tasks, status == :ok, do: net
IO.puts(inspect(generation))
generation
end
Evolution
def spawn_offspring(seed_layers, mutation_rate  @mutation_rate) do
duplicate(seed_layers, mutation_rate)
|> remove(mutation_rate)
|> Enum.map(&mutate(&1, mutation_rate))
end
Evolution
def select(pid  __MODULE__, nets) do
cutoffs = cutoffs(nets)
for net <- nets do
complexity = length(net.layers)
level = Enum.min(
[Enum.find_index(cutoffs, &(&1 >= complexity)) + 1,
complexity_levels()])
net_acc = net.test_acc
elite_acc = Map.get(get(level), :test_acc)
if is_nil(elite_acc) or net_acc > elite_acc do
put(pid, level, net)
end
end
Evolution
iex(1)> GN.Selection.get_all()
%{
1 => %GN.Network{
id: "0c2020ad-8944-4f2c-80bd-1d92c9d26535",
layers: [
dense: [64, :softrelu],
batch_norm: [],
activation: [:relu],
dropout: [0.5],
dense: [63, :relu]
],
test_acc: 0.8553
},
2 => %GN.Network{
id: "58229333-a05d-4371-8f23-e8e55c37a2ec",
layers: [
dense: [64, :relu],
Continual Learning
iex(2)> GN.Example.infinite_example()
%Task{
owner: #PID<0.171.0>,
pid: #PID<0.213.0>,
ref: #Reference<0.1968944036.911736833.180535>
}
Generations remaining: infinity
Interactive Evolution
Continual Learning
iex(2)> GN.Example.infinite_example()
%Task{
owner: #PID<0.171.0>,
pid: #PID<0.213.0>,
ref: #Reference<0.1968944036.911736833.180535>
}
Generations remaining: infinity
Interactive Evolution
iex(3)> GN.Selection.get_all() |> Map.get(2) |> GN.Library.put()
iex(4)> GN.Library.get("02b2a947-f888-4abf-b2a5-5df25668b0ee") |> GN.Selection.put_unevaluated()
Galápagos Nǎo Tech Stack
● Elixir
● Apache MXNet/Gluon
● Python
● Export/ErlPort
● Docker
● Microsoft Cognitive Toolkit*
● ONNX support*
* coming soon
Model Serialization Revisited
ONNX
● Open interchange format
● Focused on inference
● Broad and growing support
ONNX Format
message AttributeProto {
enum AttributeType {
UNDEFINED = 0;
FLOAT = 1;
INT = 2;
STRING = 3;
TENSOR = 4;
GRAPH = 5;
FLOATS = 6;
INTS = 7;
STRINGS = 8;
TENSORS = 9;
GRAPHS = 10;
}
ONNXS
iex(1)> {:ok, mnist_data} = File.read "./test/examples/mnist.onnx"
{:ok,
<<8, 3, 18, 4, 67, 78, 84, 75, 26, 3, 50, 46, 52, 40, 1, 58, 227, 206, 1, 10,
199, 80, 18, 12, 80, 97, 114, 97, 109, 101, 116, 101, 114, 49, 57, 51, 26,
12, 80, 97, 114, 97, 109, 101, 116, 101, 114, 49, ...>>}
ONNXS
iex(2)> mnist_struct = Onnx.ModelProto.decode(mnist_data)
%Onnx.ModelProto{
doc_string: nil,
domain: nil,
graph: %Onnx.GraphProto{
doc_string: nil,
initializer: [],
input: [
%Onnx.ValueInfoProto{
doc_string: nil,
name: "Input3",
type: %Onnx.TypeProto{
value: {:tensor_type,
%Onnx.TypeProto.Tensor{
elem_type: 1,
shape: %Onnx.TensorShapeProto
...
ONNXS
iex(3)> mnist_updated = %{mnist_struct | model_version: 2}
Thoughts
Model publishing and
serving are hard
problems.
Not all reactive
technologies look like
Erlang.
Reactive patterns are
useful across
toolchains.
Hard problems require
diverse sets of
solutions.
Open standards foster
rich ecosystems.
Wrapping Up
Reactive Machine Learning
Use the code
rmlsnymu
for 40% off the book!
Thanks
Questions
Tools for Making
Machine Learning
more Reactive
Jeff Smith
@jeffksmithjr
jeffsmith.tech

Weitere ähnliche Inhalte

Was ist angesagt?

My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sRoel Hartman
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTPMustafa TURAN
 
Building Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesBuilding Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesWindows Developer
 
Effective C++/WinRT for UWP and Win32
Effective C++/WinRT for UWP and Win32Effective C++/WinRT for UWP and Win32
Effective C++/WinRT for UWP and Win32Windows Developer
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful softwareJorn Oomen
 
An ADF Special Report
An ADF Special Report An ADF Special Report
An ADF Special Report Luc Bors
 
An introduction to SQLAlchemy
An introduction to SQLAlchemyAn introduction to SQLAlchemy
An introduction to SQLAlchemymengukagan
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsŁukasz Chruściel
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web servicesMichelangelo van Dam
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSVisual Engineering
 
Performance improvements tips and tricks
Performance improvements tips and tricksPerformance improvements tips and tricks
Performance improvements tips and tricksdiego bragato
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportBen Scofield
 
Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17LogeekNightUkraine
 
Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018Ortus Solutions, Corp
 
How to Create a l10n Payroll Structure
How to Create a l10n Payroll StructureHow to Create a l10n Payroll Structure
How to Create a l10n Payroll StructureOdoo
 
Why You Should Use TAPIs
Why You Should Use TAPIsWhy You Should Use TAPIs
Why You Should Use TAPIsJeffrey Kemp
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownpartsBastian Feder
 

Was ist angesagt? (20)

My Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API'sMy Top 5 APEX JavaScript API's
My Top 5 APEX JavaScript API's
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTP
 
Building Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devicesBuilding Progressive Web Apps for Windows devices
Building Progressive Web Apps for Windows devices
 
Effective C++/WinRT for UWP and Win32
Effective C++/WinRT for UWP and Win32Effective C++/WinRT for UWP and Win32
Effective C++/WinRT for UWP and Win32
 
Crafting beautiful software
Crafting beautiful softwareCrafting beautiful software
Crafting beautiful software
 
An ADF Special Report
An ADF Special Report An ADF Special Report
An ADF Special Report
 
An introduction to SQLAlchemy
An introduction to SQLAlchemyAn introduction to SQLAlchemy
An introduction to SQLAlchemy
 
Symfony World - Symfony components and design patterns
Symfony World - Symfony components and design patternsSymfony World - Symfony components and design patterns
Symfony World - Symfony components and design patterns
 
Zero to SOLID
Zero to SOLIDZero to SOLID
Zero to SOLID
 
Introduction to Zend Framework web services
Introduction to Zend Framework web servicesIntroduction to Zend Framework web services
Introduction to Zend Framework web services
 
Workshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJSWorkshop 8: Templating: Handlebars, DustJS
Workshop 8: Templating: Handlebars, DustJS
 
Performance improvements tips and tricks
Performance improvements tips and tricksPerformance improvements tips and tricks
Performance improvements tips and tricks
 
ES2015 workflows
ES2015 workflowsES2015 workflows
ES2015 workflows
 
And the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack SupportAnd the Greatest of These Is ... Rack Support
And the Greatest of These Is ... Rack Support
 
Jquery 4
Jquery 4Jquery 4
Jquery 4
 
Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17Alexey Tsoy Meta Programming in C++ 16.11.17
Alexey Tsoy Meta Programming in C++ 16.11.17
 
Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018Cfml features modern coding into the box 2018
Cfml features modern coding into the box 2018
 
How to Create a l10n Payroll Structure
How to Create a l10n Payroll StructureHow to Create a l10n Payroll Structure
How to Create a l10n Payroll Structure
 
Why You Should Use TAPIs
Why You Should Use TAPIsWhy You Should Use TAPIs
Why You Should Use TAPIs
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 

Ähnlich wie Tools for Making Machine Learning more Reactive

Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsFrancois Zaninotto
 
Concurrency on the JVM
Concurrency on the JVMConcurrency on the JVM
Concurrency on the JVMVaclav Pech
 
Flask patterns
Flask patternsFlask patterns
Flask patternsit-people
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jscacois
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Elena Kolevska
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用Felinx Lee
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5Martin Kleppe
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant TrainingAidIQ
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Jonas Bonér
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scalaparag978978
 
Finch.io - Purely Functional REST API with Finagle
Finch.io - Purely Functional REST API with FinagleFinch.io - Purely Functional REST API with Finagle
Finch.io - Purely Functional REST API with FinagleVladimir Kostyukov
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 

Ähnlich wie Tools for Making Machine Learning more Reactive (20)

Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Concurrency on the JVM
Concurrency on the JVMConcurrency on the JVM
Concurrency on the JVM
 
Flask patterns
Flask patternsFlask patterns
Flask patterns
 
Avoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.jsAvoiding Callback Hell with Async.js
Avoiding Callback Hell with Async.js
 
DataMapper
DataMapperDataMapper
DataMapper
 
Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5Bootstrat REST APIs with Laravel 5
Bootstrat REST APIs with Laravel 5
 
Play vs Rails
Play vs RailsPlay vs Rails
Play vs Rails
 
用Tornado开发RESTful API运用
用Tornado开发RESTful API运用用Tornado开发RESTful API运用
用Tornado开发RESTful API运用
 
What's new in jQuery 1.5
What's new in jQuery 1.5What's new in jQuery 1.5
What's new in jQuery 1.5
 
GHC Participant Training
GHC Participant TrainingGHC Participant Training
GHC Participant Training
 
Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)Pragmatic Real-World Scala (short version)
Pragmatic Real-World Scala (short version)
 
Pragmatic Real-World Scala
Pragmatic Real-World ScalaPragmatic Real-World Scala
Pragmatic Real-World Scala
 
Finch.io - Purely Functional REST API with Finagle
Finch.io - Purely Functional REST API with FinagleFinch.io - Purely Functional REST API with Finagle
Finch.io - Purely Functional REST API with Finagle
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 

Mehr von Jeff Smith

Questioning Conversational AI
Questioning Conversational AIQuestioning Conversational AI
Questioning Conversational AIJeff Smith
 
Neuroevolution in Elixir
Neuroevolution in ElixirNeuroevolution in Elixir
Neuroevolution in ElixirJeff Smith
 
Building Learning Agents
Building Learning AgentsBuilding Learning Agents
Building Learning AgentsJeff Smith
 
Reactive for Machine Learning Teams
Reactive for Machine Learning TeamsReactive for Machine Learning Teams
Reactive for Machine Learning TeamsJeff Smith
 
Reactive Machine Learning On and Beyond the JVM
Reactive Machine Learning On and Beyond the JVMReactive Machine Learning On and Beyond the JVM
Reactive Machine Learning On and Beyond the JVMJeff Smith
 
Bringing Data Scientists and Engineers Together
Bringing Data Scientists and Engineers TogetherBringing Data Scientists and Engineers Together
Bringing Data Scientists and Engineers TogetherJeff Smith
 
Characterizing Intelligence with Elixir
Characterizing Intelligence with ElixirCharacterizing Intelligence with Elixir
Characterizing Intelligence with ElixirJeff Smith
 
Reactive Learning Agents
Reactive Learning AgentsReactive Learning Agents
Reactive Learning AgentsJeff Smith
 
Spark for Reactive Machine Learning: Building Intelligent Agents at Scale
Spark for Reactive Machine Learning: Building Intelligent Agents at ScaleSpark for Reactive Machine Learning: Building Intelligent Agents at Scale
Spark for Reactive Machine Learning: Building Intelligent Agents at ScaleJeff Smith
 
Introducing Reactive Machine Learning
Introducing Reactive Machine LearningIntroducing Reactive Machine Learning
Introducing Reactive Machine LearningJeff Smith
 
Collecting Uncertain Data the Reactive Way
Collecting Uncertain Data the Reactive WayCollecting Uncertain Data the Reactive Way
Collecting Uncertain Data the Reactive WayJeff Smith
 
Reactive Machine Learning and Functional Programming
Reactive Machine Learning and Functional ProgrammingReactive Machine Learning and Functional Programming
Reactive Machine Learning and Functional ProgrammingJeff Smith
 
Huhdoop?: Uncertain Data Management on Non-Relational Database Systems
Huhdoop?: Uncertain Data Management on Non-Relational Database SystemsHuhdoop?: Uncertain Data Management on Non-Relational Database Systems
Huhdoop?: Uncertain Data Management on Non-Relational Database SystemsJeff Smith
 
Breadth or Depth: What's in a column-store?
Breadth or Depth: What's in a column-store?Breadth or Depth: What's in a column-store?
Breadth or Depth: What's in a column-store?Jeff Smith
 
Save the server, Save the world
Save the server, Save the worldSave the server, Save the world
Save the server, Save the worldJeff Smith
 
NoSQL in Perspective
NoSQL in PerspectiveNoSQL in Perspective
NoSQL in PerspectiveJeff Smith
 

Mehr von Jeff Smith (16)

Questioning Conversational AI
Questioning Conversational AIQuestioning Conversational AI
Questioning Conversational AI
 
Neuroevolution in Elixir
Neuroevolution in ElixirNeuroevolution in Elixir
Neuroevolution in Elixir
 
Building Learning Agents
Building Learning AgentsBuilding Learning Agents
Building Learning Agents
 
Reactive for Machine Learning Teams
Reactive for Machine Learning TeamsReactive for Machine Learning Teams
Reactive for Machine Learning Teams
 
Reactive Machine Learning On and Beyond the JVM
Reactive Machine Learning On and Beyond the JVMReactive Machine Learning On and Beyond the JVM
Reactive Machine Learning On and Beyond the JVM
 
Bringing Data Scientists and Engineers Together
Bringing Data Scientists and Engineers TogetherBringing Data Scientists and Engineers Together
Bringing Data Scientists and Engineers Together
 
Characterizing Intelligence with Elixir
Characterizing Intelligence with ElixirCharacterizing Intelligence with Elixir
Characterizing Intelligence with Elixir
 
Reactive Learning Agents
Reactive Learning AgentsReactive Learning Agents
Reactive Learning Agents
 
Spark for Reactive Machine Learning: Building Intelligent Agents at Scale
Spark for Reactive Machine Learning: Building Intelligent Agents at ScaleSpark for Reactive Machine Learning: Building Intelligent Agents at Scale
Spark for Reactive Machine Learning: Building Intelligent Agents at Scale
 
Introducing Reactive Machine Learning
Introducing Reactive Machine LearningIntroducing Reactive Machine Learning
Introducing Reactive Machine Learning
 
Collecting Uncertain Data the Reactive Way
Collecting Uncertain Data the Reactive WayCollecting Uncertain Data the Reactive Way
Collecting Uncertain Data the Reactive Way
 
Reactive Machine Learning and Functional Programming
Reactive Machine Learning and Functional ProgrammingReactive Machine Learning and Functional Programming
Reactive Machine Learning and Functional Programming
 
Huhdoop?: Uncertain Data Management on Non-Relational Database Systems
Huhdoop?: Uncertain Data Management on Non-Relational Database SystemsHuhdoop?: Uncertain Data Management on Non-Relational Database Systems
Huhdoop?: Uncertain Data Management on Non-Relational Database Systems
 
Breadth or Depth: What's in a column-store?
Breadth or Depth: What's in a column-store?Breadth or Depth: What's in a column-store?
Breadth or Depth: What's in a column-store?
 
Save the server, Save the world
Save the server, Save the worldSave the server, Save the world
Save the server, Save the world
 
NoSQL in Perspective
NoSQL in PerspectiveNoSQL in Perspective
NoSQL in Perspective
 

Kürzlich hochgeladen

HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 

Kürzlich hochgeladen (20)

Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 

Tools for Making Machine Learning more Reactive

  • 1. Tools for Making Machine Learning more Reactive Jeff Smith @jeffksmithjr jeffsmith.tech
  • 13. Akka ● Scala & Java ● Actor model ● Concurrency ● Distribution ● Supervision
  • 15. Model Microservice in Akka HTTP case class Prediction(id: Long, timestamp: Long, value: Double) trait Protocols extends DefaultJsonProtocol { implicit val predictionFormat = jsonFormat3(Prediction) }
  • 16. Model Microservice in Akka HTTP def model(features: Map[Char, Double]) = { val coefficients = ('a' to 'z').zip(1 to 26).toMap val predictionValue = features.map { case (identifier, value) => coefficients.getOrElse(identifier, 0) * value }.sum / features.size Prediction(Random.nextLong(), System.currentTimeMillis(), predictionValue) } def parseFeatures(features: String): Map[String, Double] = { features.parseJson.convertTo[Map[Char, Double]] } def predict(features: String): Prediction = { model(parseFeatures(features)) }
  • 17. Model Microservice in Akka HTTP trait Service extends Protocols { implicit val system: ActorSystem implicit def executor: ExecutionContextExecutor implicit val materializer: Materializer val logger: LoggingAdapter val routes = { logRequestResult("model-service") { pathPrefix("predict") { (get & path(Segment)) { features: String => complete { ToResponseMarshallable(predict(features))}}}}}}
  • 19. Random Forest in Spark MLlib
  • 20. MLlib Model Serialization { "class": "org.apache.spark.ml.PipelineModel", "timestamp": 1467653845388, "sparkVersion": "2.0.0-preview", "uid": "pipeline_6b4fb08e8fb0", "paramMap": { "stageUids": ["quantileDiscretizer_d3996173db25", "vecAssembler_2bdcd79fe1cf", "logreg_9d559ca7e208"] } }
  • 21. MLlib Model Serialization { "class": "org.apache.spark.ml.classification.LogisticRegressionModel", "timestamp": 1467653845650, "sparkVersion": "2.0.0-preview", "uid": "logreg_9d559ca7e208", "paramMap": { "threshold": 0.5, "elasticNetParam": 0.0, "fitIntercept": true, "tol": 1.0E-6, "regParam": 0.0, "maxIter": 5, "standardization": true, "featuresCol": "features", "rawPredictionCol": "rawPrediction", "predictionCol": "prediction", "probabilityCol": "probability", "labelCol": "label"}}
  • 24. Containerizing with sbt-docker dockerfile in docker := { val jarFile: File = sbt.Keys.`package`.in(Compile, packageBin).value val classpath = (managedClasspath in Compile).value val mainClass = "com.reactivemachinelearning.PredictiveService" val jarTarget = s"/app/${jarFile.getName}" val classpathString = classpath.files.map("/app/" + _.getName) .mkString(":") + ":" + jarTarget new Dockerfile { from("java") add(classpath.files, "/app/") add(jarFile, jarTarget) entryPoint("java", "-cp", classpathString, mainClass) } }
  • 25. Containerizing with sbt-docker FROM java ADD 0/spark-core_2.11-2.0.0-preview.jar 1/avro-mapred-1.7.7-hadoop2.jar ... ADD 166/chapter-7_2.11-1.0.jar /app/chapter-7_2.11-1.0.jar ENTRYPOINT ["java", "-cp", "/app/spark-core_2.11-2.0.0-preview.jar ... "com.reactivemachinelearning.PredictiveService"]
  • 28. Model Server in http4s object Models { val modelA = HttpService { case GET -> Root / "a" / inputData => val response = true Ok(s"Model A predicted $response.") } val modelB = HttpService { case GET -> Root / "b" / inputData => val response = false Ok(s"Model B predicted $response.") } }
  • 29. Model Server in http4s object Client { val client = PooledHttp1Client() private def call(model: String, input: String) = { val target = Uri.fromString(s"http://localhost:8080/models/$model/$input").toOption.get client.expect[String](target) } def callA(input: String) = call("a", input) def callB(input: String) = call("b", input) }
  • 30. Model Server in http4s def splitTraffic(data: String) = { data.hashCode % 10 match { case x if x < 4 => Client.callA(data) case _ => Client.callB(data) } }
  • 31. Model Server in http4s object ModelServer extends ServerApp { val apiService = HttpService { case GET -> Root / "predict" / inputData => val response = splitTraffic(inputData).run Ok(response) } override def server(args: List[String]): Task[Server] = { BlazeBuilder .bindLocal(8080) .mountService(apiService, "/api") .mountService(Models.modelA, "/models") .mountService(Models.modelB, "/models") .start } }
  • 32. Model Server in http4s import scala.util.Random val modelC = HttpService { case GET -> Root / "c" / inputData => { val workingOk = Random.nextBoolean() val response = true if (workingOk) { Ok(s"Model C predicted $response.") } else { BadRequest("Model C failed to predict.") } } }
  • 33. Model Server in http4s private def call(model: String, input: String): Task[Response] = { val target = Uri.fromString( s"http://localhost:8080/models/$model/$input" ).toOption.get client(target) } def callC(input: String) = call("c", input)
  • 34. Model Server in http4s def splitTraffic(data: String) = { data.hashCode % 10 match { case x if x < 4 => Client.callA(data) case x if x < 6 => Client.callB(data) case _ => Client.callC(data) } } val apiService = HttpService { case GET -> Root / "predict" / inputData => val response = splitTraffic(inputData).run response match { case r: Response if r.status == Ok => Response(Ok).withBody(r.bodyAsText) case r => Response(BadRequest).withBody(r.bodyAsText) } }
  • 35. Model Server in http4s def splitTraffic(data: String) = { data.hashCode % 10 match { case x if x < 4 => Client.callA(data) case x if x < 6 => Client.callB(data) case _ => Client.callC(data) } } val apiService = HttpService { case GET -> Root / "predict" / inputData => val response = splitTraffic(inputData).run response match { case r: Response if r.status == Ok => Response(Ok).withBody(r.bodyAsText) case r => Response(BadRequest).withBody(r.bodyAsText) } }
  • 36. Model Server in http4s private def call(model: String, input: String) = { val target = Uri.fromString(s"http://localhost:8080/models/$model/$input").toOption.get client(target).retry(Seq(1 second), {_ => true}) }
  • 37. BEAM
  • 41. Circuit Breakers in Erlang/Elixir def update(user_data) do {user_id, _} = user_data case verify_fuse(user_id) do :ok -> write_to_db(user_data) |> parse_db_response(user_id) :sorry -> IO.puts "This user can't be updated now. ¯_(ツ)_/¯" :sorry end end
  • 42. Circuit Breakers in Erlang/Elixir defp verify_fuse(user_id) do case :fuse.ask(user_id, :sync) do {:error, :not_found} -> IO.puts "Installing" install_fuse(user_id) :ok :blown -> :sorry _ -> :ok end end
  • 43. Circuit Breakers in Erlang/Elixir defp install_fuse(user_id) do :fuse.install(user_id, {{:standard, 3, 60000}, {:reset, 900000}}) end
  • 44. Circuit Breakers in Erlang/Elixir defp write_to_db({_user_id, _data}) do Enum.random([{:ok, ""}, {:error, "The DB dropped the ball. ಠ_ಠ"}]) end
  • 45. Circuit Breakers in Erlang/Elixir defp parse_db_response({:ok, _}, _user_id) do :ok end defp parse_db_response({:error, message}, user_id) do :fuse.melt(user_id) IO.puts "Error encountered: #{message}.nMelting the fuse!" :sorry end
  • 46. Circuit Breakers in Erlang/Elixir def update(user_data) do {user_id, _} = user_data case verify_fuse(user_id) do :ok -> write_to_db(user_data) |> parse_db_response(user_id) :sorry -> IO.puts "This user can't be updated now. ¯_(ツ)_/¯" :sorry end end
  • 47. Circuit Breakers in Akka class DangerousActor extends Actor with ActorLogging { import context.dispatcher val breaker = new CircuitBreaker( context.system.scheduler, maxFailures = 5, callTimeout = 10.seconds, resetTimeout = 1.minute).onOpen(notifyMeOnOpen()) def notifyMeOnOpen(): Unit = log.warning("My CircuitBreaker is now open, and will not close for one minute") }
  • 48. Circuit Breakers in Lagom def descriptor: Descriptor = { import Service._ named("hello").withCalls( namedCall("hi", this.sayHi), namedCall("hiAgain", this.hiAgain) .withCircuitBreaker(CircuitBreaker.identifiedBy("hello2")) ) }
  • 53. Evolution def evolve(nets, generations) do evolve(nets, generations, &decrement/1) end def evolve(nets, generations, count_function) when generations > 0 do Task.Supervisor.async(GN.TaskSupervisor, fn -> IO.puts("Generations remaining: #{generations}") learn_generation(nets) |> select() |> evolve(count_function.(generations), count_function) end) end def evolve(nets, _generations, _count_function) do nets end
  • 54. Evolution def learn_generation(nets) do clean_nets = strip_empties(nets) tasks = Task.Supervisor.async_stream_nolink( GN.TaskSupervisor, clean_nets, &start_and_spawn(&1), timeout: GN.Parameters.get(__MODULE__, :timeout) ) generation = for {status, net} <- tasks, status == :ok, do: net IO.puts(inspect(generation)) generation end
  • 55. Evolution def spawn_offspring(seed_layers, mutation_rate @mutation_rate) do duplicate(seed_layers, mutation_rate) |> remove(mutation_rate) |> Enum.map(&mutate(&1, mutation_rate)) end
  • 56. Evolution def select(pid __MODULE__, nets) do cutoffs = cutoffs(nets) for net <- nets do complexity = length(net.layers) level = Enum.min( [Enum.find_index(cutoffs, &(&1 >= complexity)) + 1, complexity_levels()]) net_acc = net.test_acc elite_acc = Map.get(get(level), :test_acc) if is_nil(elite_acc) or net_acc > elite_acc do put(pid, level, net) end end
  • 57. Evolution iex(1)> GN.Selection.get_all() %{ 1 => %GN.Network{ id: "0c2020ad-8944-4f2c-80bd-1d92c9d26535", layers: [ dense: [64, :softrelu], batch_norm: [], activation: [:relu], dropout: [0.5], dense: [63, :relu] ], test_acc: 0.8553 }, 2 => %GN.Network{ id: "58229333-a05d-4371-8f23-e8e55c37a2ec", layers: [ dense: [64, :relu],
  • 58. Continual Learning iex(2)> GN.Example.infinite_example() %Task{ owner: #PID<0.171.0>, pid: #PID<0.213.0>, ref: #Reference<0.1968944036.911736833.180535> } Generations remaining: infinity
  • 60. Continual Learning iex(2)> GN.Example.infinite_example() %Task{ owner: #PID<0.171.0>, pid: #PID<0.213.0>, ref: #Reference<0.1968944036.911736833.180535> } Generations remaining: infinity
  • 61. Interactive Evolution iex(3)> GN.Selection.get_all() |> Map.get(2) |> GN.Library.put() iex(4)> GN.Library.get("02b2a947-f888-4abf-b2a5-5df25668b0ee") |> GN.Selection.put_unevaluated()
  • 62. Galápagos Nǎo Tech Stack ● Elixir ● Apache MXNet/Gluon ● Python ● Export/ErlPort ● Docker ● Microsoft Cognitive Toolkit* ● ONNX support* * coming soon
  • 64. ONNX ● Open interchange format ● Focused on inference ● Broad and growing support
  • 65. ONNX Format message AttributeProto { enum AttributeType { UNDEFINED = 0; FLOAT = 1; INT = 2; STRING = 3; TENSOR = 4; GRAPH = 5; FLOATS = 6; INTS = 7; STRINGS = 8; TENSORS = 9; GRAPHS = 10; }
  • 66. ONNXS iex(1)> {:ok, mnist_data} = File.read "./test/examples/mnist.onnx" {:ok, <<8, 3, 18, 4, 67, 78, 84, 75, 26, 3, 50, 46, 52, 40, 1, 58, 227, 206, 1, 10, 199, 80, 18, 12, 80, 97, 114, 97, 109, 101, 116, 101, 114, 49, 57, 51, 26, 12, 80, 97, 114, 97, 109, 101, 116, 101, 114, 49, ...>>}
  • 67. ONNXS iex(2)> mnist_struct = Onnx.ModelProto.decode(mnist_data) %Onnx.ModelProto{ doc_string: nil, domain: nil, graph: %Onnx.GraphProto{ doc_string: nil, initializer: [], input: [ %Onnx.ValueInfoProto{ doc_string: nil, name: "Input3", type: %Onnx.TypeProto{ value: {:tensor_type, %Onnx.TypeProto.Tensor{ elem_type: 1, shape: %Onnx.TensorShapeProto ...
  • 68. ONNXS iex(3)> mnist_updated = %{mnist_struct | model_version: 2}
  • 70. Model publishing and serving are hard problems.
  • 71. Not all reactive technologies look like Erlang.
  • 72. Reactive patterns are useful across toolchains.
  • 73. Hard problems require diverse sets of solutions.
  • 76. Reactive Machine Learning Use the code rmlsnymu for 40% off the book!
  • 79. Tools for Making Machine Learning more Reactive Jeff Smith @jeffksmithjr jeffsmith.tech