Code Monkey home page Code Monkey logo

kaldiwebrtcserver's Introduction

Kaldi WebRTC server demo

This is a demonstration of realtime online speech recognition using the Kaldi speech recognition toolkit.

It uses WebRTC to communicate between the server and the browser. It sends audio from the user's microphone using the WebRTC audio track and sends text from the server to the browser using the WebRTC datachannel (most commonly used for sending chat messages).

The server program is written in Python. It uses aiohttp to display the web-page and serve other static data (javascript, CSS. images). For WebRTC functionality it uses the excellent aiortc library. The system requires only one Python server running, but supports multiple Kaldi instances in the background. Once it receives a request from the browser it opens a connection to the Kaldi engine and keeps forwarding audio and text between Kaldi and the user's browser.

Usage

The easiest way to use this program is with Docker, as described below. The following section explains how the program available here works.

The server loads a JSON configuration file as an argument to the program. The configuration file defines the hosts and ports of the Kaldi engines, as well as their samplerate (different models can have different sample rates).

In the future, I plan to add the option to include different types of engines (eg. for different languages) that can be picked from the website.

After loading the configuration, the server creates a queue and simply takes engines from the queue as they are requested. If the queue gets exhausted, an error 500 is returned. Simply put, you need as many engines runnning, as the number of concurrent browser sessions you intend to support.

Kaldi

This server relies on the connection with the online2-tcp-nnet3-decode-faster program. If you want to install it on your own, please follow the official instructions for installing Kaldi. You can find a brief version of that in docker/kaldi/Dockerfile.

Docker

This is the simplest way of setting up and testing this project. I have created a couple of Docker images with all the neccessary components and uploaded them to docker hub. In order to use them, you don't need to copy anything from this repository. You just need to have Docker installed and run the commands as described below.

In addition to Docker, you will need to have the docker-compose program installed. This program allows to easily start several containers at once simply by changing the configuration in a yml file. A sample is provided in docker/docker-compose.yml.

To run the server, simply copy the docker/docker-compose.yml and the required docker/servers.json files into a folder of your choice and run: docker-compose up -d

First time you run it, the program will download the images from Dockerhub so it may take a little while. Once it's running, you can run docker-compose logs -f to monitor the logs of the running servers.

At any time you can run docker-compose stop to temporarily shutdown and docker-compose start to restart the service. Finally, you can run docker-compose down to stop and remove the containers altogether.

If you want to set up more Kaldi engines, you need to edit both the docker-compose.yml and servers.json files.

More details on the dockerfiles is provided in this document.

kaldiwebrtcserver's People

Contributors

danijel3 avatar milochen0418 avatar rafnie avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kaldiwebrtcserver's Issues

Waiting for client...

Hello, I can't figure out what am I doing wrong. I can't get your web demo to work without using docker images. I'm on Ubuntu 18.04 (with Python 3.6.9), using Chromium Web Browser. My setup is supposed to be identical to your docker files.

  • Kaldi's TCP server for nnet3 online decoding online2-tcp-nnet3-decode-faster works fine on its own.
  • getUserMedia() works.
  • Right after the Kaldi's TCP server accepts connection there is either "stream over" or "socket timeout".
  • Python server initially seems to connect and then fails.
  • Moreover, if left hanging, it ends up freezing the OS (completely unresponsive).

Any idea what could be the reason?
I'll attach all the logs below.
Thanks in advance.

server

======== Running on https://0.0.0.0:20005 ========
(Press CTRL+C to quit)
[2020-05-25 16:50:22,946] aiohttp.access <INFO> 127.0.0.1 [25/May/2020:07:50:22 +0000] "GET / HTTP/1.1" 200 1771 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36"
[2020-05-25 16:50:22,971] aiohttp.access <INFO> 127.0.0.1 [25/May/2020:07:50:22 +0000] "GET /static/styles.css HTTP/1.1" 200 479 "https://0.0.0.0:20005/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36"
[2020-05-25 16:50:22,981] aiohttp.access <INFO> 127.0.0.1 [25/May/2020:07:50:22 +0000] "GET /static/client.js HTTP/1.1" 200 4683 "https://0.0.0.0:20005/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36"
[2020-05-25 16:50:22,986] aiohttp.access <INFO> 127.0.0.1 [25/May/2020:07:50:22 +0000] "GET /static/kaldi_logo.png HTTP/1.1" 200 41172 "https://0.0.0.0:20005/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36"
[2020-05-25 16:50:23,033] aiohttp.access <INFO> 127.0.0.1 [25/May/2020:07:50:23 +0000] "GET /favicon.ico HTTP/1.1" 404 172 "https://0.0.0.0:20005/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36"
[2020-05-25 16:50:32,319] ice <INFO> Connection(0) Check CandidatePair(('192.168.0.187', 54795) -> ('192.168.0.187', 58026)) State.FROZEN -> State.WAITING
[2020-05-25 16:50:32,319] ice <INFO> Connection(0) Check CandidatePair(('fec0:1::5ff:1818:def1:3909', 52926) -> ('fec0:1::5ff:1818:def1:3909', 40038)) State.FROZEN -> State.WAITING
[2020-05-25 16:50:32,319] ice <INFO> Connection(0) Check CandidatePair(('fec0:1::cb74:6406:ceba:ea7c', 47849) -> ('fec0:1::5ff:1818:def1:3909', 40038)) State.FROZEN -> State.WAITING
[2020-05-25 16:50:32,320] ice <INFO> Connection(0) Check CandidatePair(('192.168.0.187', 54795) -> ('192.168.0.187', 58026)) State.WAITING -> State.IN_PROGRESS
[2020-05-25 16:50:32,320] web <INFO> Connected to Kaldi server localhost:5050...
[2020-05-25 16:50:32,321] aiohttp.access <INFO> 127.0.0.1 [25/May/2020:07:50:32 +0000] "POST /offer HTTP/1.1" 200 2157 "https://0.0.0.0:20005/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) snap Chromium/83.0.4103.61 Chrome/83.0.4103.61 Safari/537.36"
[2020-05-25 16:50:32,322] ice <INFO> Connection(0) Check CandidatePair(('192.168.0.187', 54795) -> ('192.168.0.187', 58026)) State.IN_PROGRESS -> State.SUCCEEDED
[2020-05-25 16:50:32,341] ice <INFO> Connection(0) Check CandidatePair(('fec0:1::5ff:1818:def1:3909', 52926) -> ('fec0:1::5ff:1818:def1:3909', 40038)) State.WAITING -> State.IN_PROGRESS
[2020-05-25 16:50:32,346] ice <INFO> Connection(0) Check CandidatePair(('fec0:1::5ff:1818:def1:3909', 52926) -> ('fec0:1::5ff:1818:def1:3909', 40038)) State.IN_PROGRESS -> State.SUCCEEDED
[2020-05-25 16:50:32,347] ice <INFO> Connection(0) Check CandidatePair(('fec0:1::cb74:6406:ceba:ea7c', 47849) -> ('fec0:1::5ff:1818:def1:3909', 40038)) State.WAITING -> State.FAILED
[2020-05-25 16:50:32,347] ice <INFO> Connection(0) ICE completed

online2_tcp_nnet3_decode_faster

/home/alena/kaldi/src/online2bin/online2-tcp-nnet3-decode-faster --mfcc-config=/home/alena/data/models/streaming/exp/chain_rvb/tdnn1n_rvb_online/conf/mfcc.conf --ivector-extraction-config=/home/alena/data/models/streaming/exp/chain_rvb/tdnn1n_rvb_online/conf/ivector_extractor.conf --frames-per-chunk=20 --extra-left-context-initial=0 --min-active=200 --max-active=7000 --beam=15.0 --lattice-beam=6.0 --acoustic-scale=1.0 --endpoint.silence-phones=1:2:3:4:5:6:7:8:9:10 --chunk-length=0.2 --port-num=5050 --samp-freq=16000 /home/alena/data/models/streaming/exp/chain_rvb/tdnn1n_rvb_online/final.mdl /home/alena/data/models/streaming/exp/chain_rvb/tree_a/graph_tgsmall/HCLG.fst /home/alena/data/models/streaming/exp/chain_rvb/tree_a/graph_tgsmall/words.txt 
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:ComputeDerivedVars():ivector-extractor.cc:183) Computing derived variables for iVector extractor
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:ComputeDerivedVars():ivector-extractor.cc:204) Done.
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:RemoveOrphanNodes():nnet-nnet.cc:948) Removed 1 orphan nodes.
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:RemoveOrphanComponents():nnet-nnet.cc:847) Removing 2 orphan components.
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:Collapse():nnet-utils.cc:1472) Added 1 components, removed 2
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:CompileLooped():nnet-compile-looped.cc:345) Spent 0.020118 seconds in looped compilation.
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:Listen():online2-tcp-nnet3-decode-faster.cc:389) TcpServer: Listening on port: 5050
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:Accept():online2-tcp-nnet3-decode-faster.cc:403) Waiting for client...
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:Accept():online2-tcp-nnet3-decode-faster.cc:422) Accepted connection from: 127.0.0.1
WARNING (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:ReadChunk():online2-tcp-nnet3-decode-faster.cc:451) Stream over...
LOG (online2-tcp-nnet3-decode-faster[5.5.697~1-79790]:Accept():online2-tcp-nnet3-decode-faster.cc:403) Waiting for client...

webclient:

:20005/favicon.ico:1 Failed to load resource: the server responded with a status of 404 (Not Found)
client.js:51 v=0
o=- 7335280967440572680 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic: WMS f2Boi5mjI9HUXp13aFT0HXZ10RU6b7DVcvfi
m=audio 58026 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 192.168.0.187
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:3534240702 1 udp 2122260223 192.168.0.187 58026 typ host generation 0 network-id 1
a=candidate:312762591 1 udp 2122187263 fec0:1::5ff:1818:def1:3909 40038 typ host generation 0 network-id 2
a=candidate:2620114766 1 tcp 1518280447 192.168.0.187 9 typ host tcptype active generation 0 network-id 1
a=candidate:1546099759 1 tcp 1518207487 fec0:1::5ff:1818:def1:3909 9 typ host tcptype active generation 0 network-id 2
a=ice-ufrag:JDS0
a=ice-pwd:DGsK493N7+qaaDoDDpc86J+T
a=ice-options:trickle
a=fingerprint:sha-256 00:53:B9:6D:17:D9:1B:A7:57:B8:6A:BB:01:B7:08:3C:23:0E:1D:B2:AD:1F:D2:23:7D:80:49:B8:B3:35:95:1C
a=setup:actpass
a=mid:0
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:5 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:6 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=sendrecv
a=msid:f2Boi5mjI9HUXp13aFT0HXZ10RU6b7DVcvfi 16c168d7-bb9e-44d5-af48-083d52f4402d
a=rtcp-mux
a=rtpmap:111 opus/48000/2
a=rtcp-fb:111 transport-cc
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ssrc:718321399 cname:fVPRvfp20LnS42fV
a=ssrc:718321399 msid:f2Boi5mjI9HUXp13aFT0HXZ10RU6b7DVcvfi 16c168d7-bb9e-44d5-af48-083d52f4402d
a=ssrc:718321399 mslabel:f2Boi5mjI9HUXp13aFT0HXZ10RU6b7DVcvfi
a=ssrc:718321399 label:16c168d7-bb9e-44d5-af48-083d52f4402d
m=application 41011 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.168.0.187
a=candidate:3534240702 1 udp 2122260223 192.168.0.187 41011 typ host generation 0 network-id 1
a=candidate:312762591 1 udp 2122187263 fec0:1::5ff:1818:def1:3909 54221 typ host generation 0 network-id 2
a=candidate:2620114766 1 tcp 1518280447 192.168.0.187 9 typ host tcptype active generation 0 network-id 1
a=candidate:1546099759 1 tcp 1518207487 fec0:1::5ff:1818:def1:3909 9 typ host tcptype active generation 0 network-id 2
a=ice-ufrag:JDS0
a=ice-pwd:DGsK493N7+qaaDoDDpc86J+T
a=ice-options:trickle
a=fingerprint:sha-256 00:53:B9:6D:17:D9:1B:A7:57:B8:6A:BB:01:B7:08:3C:23:0E:1D:B2:AD:1F:D2:23:7D:80:49:B8:B3:35:95:1C
a=setup:actpass
a=mid:1
a=sctp-port:5000
a=max-message-size:262144

client.js:65 v=0
o=- 3799381832 3799381832 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE 0 1
a=msid-semantic:WMS *
m=audio 54795 UDP/TLS/RTP/SAVPF 111 0 8
c=IN IP4 192.168.0.187
a=recvonly
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=mid:0
a=msid:4ba6e709-7be7-41c1-9802-e051d00b04cf 83afb08c-a834-4606-a644-263c5d571605
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:3938142756 cname:2261fb71-251b-4a9b-be99-5032f6253ac3
a=rtpmap:111 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=candidate:9423bef4cfcc3192610fbd8172d4ee92 1 udp 2130706431 192.168.0.187 54795 typ host
a=candidate:00aa5f6846094859d2c1c6c178db7bb2 1 udp 2130706431 fec0:1::5ff:1818:def1:3909 52926 typ host
a=candidate:d4f7b767d19ac5e1a8478710b0a1451d 1 udp 2130706431 fec0:1::cb74:6406:ceba:ea7c 47849 typ host
a=candidate:f5d377bd7da58ddbbb1be970a7c16452 1 udp 1694498815 61.75.36.69 54795 typ srflx raddr 192.168.0.187 rport 54795
a=end-of-candidates
a=ice-ufrag:He0b
a=ice-pwd:CBbmhQQPiNLEHzq7kpuAZm
a=fingerprint:sha-256 DD:6A:9E:15:70:5C:E8:9C:F3:5A:96:0E:5D:DC:B6:12:77:57:21:A6:65:D5:43:84:B4:3F:F9:CD:2C:F1:AB:56
a=setup:active
m=application 54795 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 192.168.0.187
a=mid:1
a=sctp-port:5000
a=max-message-size:65536
a=candidate:9423bef4cfcc3192610fbd8172d4ee92 1 udp 2130706431 192.168.0.187 54795 typ host
a=candidate:00aa5f6846094859d2c1c6c178db7bb2 1 udp 2130706431 fec0:1::5ff:1818:def1:3909 52926 typ host
a=candidate:d4f7b767d19ac5e1a8478710b0a1451d 1 udp 2130706431 fec0:1::cb74:6406:ceba:ea7c 47849 typ host
a=candidate:f5d377bd7da58ddbbb1be970a7c16452 1 udp 1694498815 61.75.36.69 54795 typ srflx raddr 192.168.0.187 rport 54795
a=end-of-candidates
a=ice-ufrag:He0b
a=ice-pwd:CBbmhQQPiNLEHzq7kpuAZm
a=fingerprint:sha-256 DD:6A:9E:15:70:5C:E8:9C:F3:5A:96:0E:5D:DC:B6:12:77:57:21:A6:65:D5:43:84:B4:3F:F9:CD:2C:F1:AB:56
a=setup:active

client.js:94 Opened data channel
client.js:118 Disconnected

gpu decoding

Hi
Now Kaldi support GPU decoding (kaldi-asr/kaldi#3114) is it possible to configure TCP port on GPU?
What your opinion?
How can change TCP port to use GPU decoding?
Best regards

doesn't work on ubuntu

Hello, @danijel3 ! Nice work, I have tested this on macbook and all works well, but on Ubuntu after I click Start button, and allowed use micro, all pending in Connecting status.
In docker logs I see this

web_1    | [2019-04-08 19:24:37,573] ice <INFO> Connection(0) Check CandidatePair(('172.27.0.3', 45489) -> ('192.168.1.2', 43511)) State.FROZEN -> State.WAITING
web_1    | [2019-04-08 19:24:37,573] ice <INFO> Connection(0) Check CandidatePair(('172.27.0.3', 45489) -> ('192.168.1.2', 43511)) State.WAITING -> State.IN_PROGRESS
kaldi_1  | LOG (online2-tcp-nnet3-decode-faster[5.5.259~1-25269]:Accept():online2-tcp-nnet3-decode-faster.cc:364) Accepted connection from: 172.27.0.3
web_1    | [2019-04-08 19:24:37,575] ice <INFO> Connection(0) Check CandidatePair(('172.27.0.3', 45489) -> ('192.168.1.2', 43511)) failed : source address mismatch
web_1    | [2019-04-08 19:24:37,575] ice <INFO> Connection(0) Check CandidatePair(('172.27.0.3', 45489) -> ('192.168.1.2', 43511)) State.IN_PROGRESS -> State.FAILED
web_1    | [2019-04-08 19:24:37,575] ice <INFO> Connection(0) ICE failed
web_1    | [2019-04-08 19:24:37,576] web <INFO> Connected to Kaldi server kaldi:5050...

Specifically -- source address mismatch, which doesn't appear on macbook.
What should I check for this?

Docker image needs to support https

The docker image does not support HTTPS. Without HTTPS, chrome will not allow use of navigator.mediaDevices.getUserMedia, and thus the script errors out and the demo fails.

The error that shows up in to logs if the website is called with HTTPS is:
[2020-10-09 13:48:19,546] aiohttp.server Error handling request
Traceback (most recent call last):
File "/usr/local/lib/python3.7/dist-packages/aiohttp/web_protocol.py", line 275, in data_received
messages, upgraded, tail = self._request_parser.feed_data(data)
File "aiohttp/_http_parser.pyx", line 523, in aiohttp._http_parser.HttpParser.feed_data
aiohttp.http_exceptions.BadStatusLine: invalid HTTP method

Issue with setting up KaldiWebrtcServer on AWS ec2 instance

What I have done so far

  • I updated the Dockerfile in the web folder by adding a line "pip3 install --upgrade aiortc" to fix an issue, when a request was sent to the service it was displaying an error "unkown ip address format". This fixed it.
  • I setup nginx as a reverse proxy so i can use certbot to create a certificate to use a FQDN (Fully qualified domain name)
  • I ran the command sudo docker-compose up -d.

The issue

  • when i access the url to view the webpage it only loads the html file. The js and css files aren't found (as the error 404 describes in the console)

However

  • If i access the page via the ip address https://ipadress it loads the webpage with all the files.
  • I click the start button it turns red and shows connecting for a while then
  • I get a long message from client.js on line 51
  • Then i get a POST error message service unavailable at the /offer route
  • then followed by a syntax error from client.js on line 68

Has anyone successfully deployed this on an ec2 instance without any issues or can anyone assist with these problems I'm encountering.

Always connecting...

Hi ,I install this project follow your steps on the linux server,
(1)docker-compose up -d
(2)docker-compose logs -f
and it has no error and running sucessfully,LOG AS FOLLOWS:
.......
kaldi_1 | LOG (online2-tcp-nnet3-decode-faster[5.5.259~1-25269]:Accept():online2-tcp-nnet3-decode-faster.cc:345) Waiting for client...

Then I test on my computer , the computer and server in same local area network. when i print the url as http://myipaddress:8080/ ,the browser shows webpage sucessfully.
and press "Start button",it shows tip text Connecting... all the time.

how can i solve the problem?

Huge memory consumption by server

Hi @danijel3
There is problem with huge memory consumption by the server in some situations.
I debug it a little bit and I found that it is caused by wrong connection handling in case of errors in __audio_task.
At example:
When the client side starts the stream and after a moment stops it for some time and finally run streaming again, then the server starts consuming RAM with linear speed until all memory in the system is used.
It is caused by such masked exception:

Traceback (most recent call last):
  File "/server/kaldi.py", line 72, in __run_audio_xfer
    frame = self.__resampler.resample(frame)
  File "av/audio/resampler.pyx", line 39, in av.audio.resampler.AudioResampler.resample
  File "av/audio/resampler.pyx", line 123, in av.audio.resampler.AudioResampler.resample
ValueError: Input frame pts 55137600 != expected 55133760; fix or set to None.

I prepared fix for that which improved connection handling in case of exceptions.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.