Pickling Models for Persistence#
This notebook demonstrates simple pickling of both single-GPU and multi-GPU cuML models for persistence
[1]:
import warnings
warnings.filterwarnings("ignore", category=FutureWarning)
Single GPU Model Pickling#
All single-GPU estimators are pickleable. The following example demonstrates the creation of a synthetic dataset, training, and pickling of the resulting model for storage. Trained single-GPU models can also be used to distribute the inference on a Dask cluster, which the Distributed Model Pickling
section below demonstrates.
[2]:
from cuml.datasets import make_blobs
X, y = make_blobs(n_samples=50,
n_features=10,
centers=5,
cluster_std=0.4,
random_state=0)
[3]:
from cuml.cluster import KMeans
model = KMeans(n_clusters=5)
model.fit(X)
[3]:
KMeans()
[4]:
import pickle
pickle.dump(model, open("kmeans_model.pkl", "wb"))
[5]:
model = pickle.load(open("kmeans_model.pkl", "rb"))
[6]:
model.cluster_centers_
[6]:
array([[ 4.6749854 , 8.213466 , -9.075721 , 9.568374 , 8.454807 ,
-1.2327975 , 3.3903713 , -7.8282413 , -0.8454461 , 0.62885725],
[-3.008261 , 4.6259604 , -4.4832497 , 2.228457 , 1.643532 ,
-2.4505193 , -5.258201 , -1.6679404 , -7.985753 , 2.8311467 ],
[-4.243999 , 5.610707 , -5.669777 , -1.7957242 , -9.255529 ,
0.7177438 , 4.44359 , -2.8747153 , -5.0900965 , 9.684121 ],
[-5.6072407 , 2.2695985 , -3.7516537 , -1.8182005 , -5.143028 ,
7.599363 , 2.8252368 , 8.773043 , 1.6198314 , 1.1772048 ],
[ 5.261548 , -4.0487256 , 4.464928 , -2.9367518 , 3.5061095 ,
-4.016832 , -3.463885 , 6.078449 , -6.953326 , -1.004144 ]],
dtype=float32)
Distributed Model Pickling#
The distributed estimator wrappers inside of the cuml.dask
are not intended to be pickled directly. The Dask cuML estimators provide a function get_combined_model()
, which returns the trained single-GPU model for pickling. The combined model can be used for inference on a single-GPU, and the ParallelPostFit
wrapper from the Dask-ML library can be used to perform distributed inference on a Dask cluster.
[7]:
from dask.distributed import Client
from dask_cuda import LocalCUDACluster
cluster = LocalCUDACluster()
client = Client(cluster)
client
2022-12-21 19:30:26,770 - distributed.preloading - INFO - Creating preload: dask_cuda.initialize
2022-12-21 19:30:26,770 - distributed.preloading - INFO - Import preload module: dask_cuda.initialize
2022-12-21 19:30:26,782 - distributed.preloading - INFO - Creating preload: dask_cuda.initialize
2022-12-21 19:30:26,782 - distributed.preloading - INFO - Import preload module: dask_cuda.initialize
[7]:
Client
Client-ec1fbb5f-8165-11ed-9103-0242ac110004
Connection method: Cluster object | Cluster type: dask_cuda.LocalCUDACluster |
Dashboard: http://127.0.0.1:8787/status |
Cluster Info
LocalCUDACluster
c2601fcd
Dashboard: http://127.0.0.1:8787/status | Workers: 2 |
Total threads: 2 | Total memory: 45.78 GiB |
Status: running | Using processes: True |
Scheduler Info
Scheduler
Scheduler-443520b6-dfc4-400b-983e-02096e392988
Comm: tcp://127.0.0.1:41183 | Workers: 2 |
Dashboard: http://127.0.0.1:8787/status | Total threads: 2 |
Started: Just now | Total memory: 45.78 GiB |
Workers
Worker: 0
Comm: tcp://127.0.0.1:33335 | Total threads: 1 |
Dashboard: http://127.0.0.1:42041/status | Memory: 22.89 GiB |
Nanny: tcp://127.0.0.1:38659 | |
Local directory: /tmp/dask-worker-space/worker-lbi0z08f | |
GPU: Quadro GV100 | GPU memory: 32.00 GiB |
Worker: 1
Comm: tcp://127.0.0.1:34939 | Total threads: 1 |
Dashboard: http://127.0.0.1:44677/status | Memory: 22.89 GiB |
Nanny: tcp://127.0.0.1:35571 | |
Local directory: /tmp/dask-worker-space/worker-z567dshn | |
GPU: Quadro GV100 | GPU memory: 32.00 GiB |
[8]:
from cuml.dask.datasets import make_blobs
n_workers = len(client.scheduler_info()["workers"].keys())
X, y = make_blobs(n_samples=5000,
n_features=30,
centers=5,
cluster_std=0.4,
random_state=0,
n_parts=n_workers*5)
X = X.persist()
y = y.persist()
[9]:
from cuml.dask.cluster import KMeans
dist_model = KMeans(n_clusters=5)
[10]:
dist_model.fit(X)
2022-12-21 19:30:34,214 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-20bc5cb2-5d28-4130-9e14-384183655dc2
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,235 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-15ef16f1-15e3-45c2-9b6c-44b4705f1ddf
Function: _get_model_attr
args: (KMeansMG(), '_ipython_display_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_display_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,249 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-5b46a30a-e363-41b3-93d7-7ce58b3c45f6
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,269 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-0247c667-9905-4952-8f40-da2fc814dff2
Function: _get_model_attr
args: (KMeansMG(), '_repr_mimebundle_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_mimebundle_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,291 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-1461e427-51c5-4507-a82f-18e2d0e34156
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,310 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-65142208-72ab-4769-931a-99c2ad94b122
Function: _get_model_attr
args: (KMeansMG(), '_repr_html_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_html_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,331 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-5f8c33f6-9431-4bd8-a157-4c23feba661b
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,352 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-4e784d55-68ef-4cc1-a686-b204361e9b79
Function: _get_model_attr
args: (KMeansMG(), '_repr_markdown_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_markdown_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,367 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-c70a9389-2e00-4305-981f-f1a733e7e96d
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,390 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-c57b601d-1e47-48ee-b833-33afae46c0fd
Function: _get_model_attr
args: (KMeansMG(), '_repr_svg_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_svg_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,416 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-182479b3-e42f-4d2c-9676-432d23450f66
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,437 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-41b31914-0dcd-4323-994e-dddd9a5adeb3
Function: _get_model_attr
args: (KMeansMG(), '_repr_png_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_png_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,462 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-a00b3324-f8e7-4368-aff4-a89a3d13a1db
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,491 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-d5f8185c-80bb-4d54-b4d0-7f49554808b9
Function: _get_model_attr
args: (KMeansMG(), '_repr_pdf_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_pdf_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,522 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-47c3865a-5d72-41b3-a3ac-9931e0f2544b
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,545 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-7fe59d11-a17b-48ea-bfd6-ed2dbe432a44
Function: _get_model_attr
args: (KMeansMG(), '_repr_jpeg_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_jpeg_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,565 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-a92e5adf-1622-455e-a36d-979ef225cc1c
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,592 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-b083f2b1-3f6e-4d73-8c55-7040d0a6eac4
Function: _get_model_attr
args: (KMeansMG(), '_repr_latex_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_latex_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,618 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-b48f5896-b15f-42a6-8051-6d84e35afe66
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,633 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-d030ba8e-dee3-491c-bcee-d4cfd03cd2ec
Function: _get_model_attr
args: (KMeansMG(), '_repr_json_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_json_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,656 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-edcc393d-32da-4a44-a349-f81b9325fbb0
Function: _get_model_attr
args: (KMeansMG(), '_ipython_canary_method_should_not_exist_')
kwargs: {}
Exception: 'AttributeError("Attribute _ipython_canary_method_should_not_exist_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
2022-12-21 19:30:34,678 - distributed.worker - WARNING - Compute Failed
Key: _get_model_attr-893ab5ea-9180-4625-81b8-5cce9cc4a91e
Function: _get_model_attr
args: (KMeansMG(), '_repr_javascript_')
kwargs: {}
Exception: 'AttributeError("Attribute _repr_javascript_ does not exist on model <class \'cuml.cluster.kmeans_mg.KMeansMG\'>")'
[10]:
<cuml.dask.cluster.kmeans.KMeans at 0x7f7807228a90>
[11]:
import pickle
single_gpu_model = dist_model.get_combined_model()
pickle.dump(single_gpu_model, open("kmeans_model.pkl", "wb"))
[12]:
single_gpu_model = pickle.load(open("kmeans_model.pkl", "rb"))
[13]:
single_gpu_model.cluster_centers_
[13]:
array([[-2.8722034 , 4.4697323 , -4.4313636 , 2.3996632 , 1.7438416 ,
-2.4938557 , -5.221266 , -1.7067921 , -8.130272 , 2.6409216 ,
-4.307932 , 5.5793056 , -5.741946 , -1.7193329 , -9.359334 ,
0.7162488 , 4.443801 , -2.9173877 , -4.9321456 , 9.692949 ,
8.393694 , -6.2387223 , -6.3638473 , 1.9633775 , 4.162585 ,
-9.159683 , 4.611743 , 8.801129 , 6.8551826 , 2.2458153 ],
[ 4.799147 , 8.402423 , -9.21459 , 9.392471 , 8.512868 ,
-1.0980052 , 3.325824 , -7.8028507 , -0.5990245 , 0.25806773,
5.5174665 , -4.113201 , 4.2922897 , -2.8411756 , 3.6327314 ,
-4.173102 , -3.6205478 , 6.2173696 , -6.9105296 , -1.0845209 ,
-5.853915 , 2.237582 , -3.8543427 , -1.6783282 , -5.322575 ,
7.575618 , 2.9321437 , 8.521328 , 1.5875129 , 1.0917971 ],
[-6.9281073 , -9.766994 , -6.513839 , -0.43525624, 6.100162 ,
3.7533102 , -3.9653103 , 6.1827755 , -1.850568 , 5.028263 ,
-6.8437643 , 1.3515668 , 8.996504 , -1.0031246 , 9.674833 ,
9.769712 , -8.616945 , 5.982676 , 2.2226048 , -3.6281197 ,
7.0979915 , -7.3974366 , -5.314036 , -6.9729123 , -7.9171205 ,
6.6703362 , -5.5767236 , 7.1343427 , 6.606859 , -8.299494 ],
[-4.6557665 , -9.605046 , 6.6639013 , 4.435602 , 2.1566877 ,
2.599673 , 0.6010148 , 6.262878 , -8.829993 , -0.3944551 ,
9.801518 , 7.5849943 , 10.004723 , -5.871636 , -1.2833362 ,
-2.5475292 , -1.0870931 , -5.2439103 , -9.321918 , 4.6081576 ,
-0.10159794, -3.9462261 , 6.186966 , -7.401992 , 5.656775 ,
-8.548569 , -7.5288205 , -5.5547523 , 4.8490367 , 2.5301979 ],
[ 6.2598987 , 9.218424 , 8.374798 , 9.035375 , 7.7094774 ,
-1.0123167 , -6.256305 , 1.3844212 , -6.9562526 , -5.9650974 ,
1.0701919 , -0.02766198, 2.8116884 , 1.8430994 , -8.250474 ,
3.057016 , -8.495887 , 9.738966 , -7.748305 , 3.4321914 ,
-3.943902 , -4.113307 , 2.6874824 , 1.2842505 , 1.019016 ,
5.261929 , -1.6500074 , 6.161519 , -6.911384 , -9.656554 ]],
dtype=float32)
Exporting cuML Random Forest models for inferencing on machines without GPUs#
Starting with cuML version 21.06, you can export cuML Random Forest models and run predictions with them on machines without an NVIDIA GPUs. The Treelite package defines an efficient exchange format that lets you portably move the cuML Random Forest models to other machines. We will refer to the exchange format as “checkpoints.”
Here are the steps to export the model:
Call
to_treelite_checkpoint()
to obtain the checkpoint file from the cuML Random Forest model.
[14]:
from cuml.ensemble import RandomForestClassifier as cumlRandomForestClassifier
from sklearn.datasets import load_iris
import numpy as np
X, y = load_iris(return_X_y=True)
X, y = X.astype(np.float32), y.astype(np.int32)
clf = cumlRandomForestClassifier(max_depth=3, random_state=0, n_estimators=10)
clf.fit(X, y)
checkpoint_path = './checkpoint.tl'
# Export cuML RF model as Treelite checkpoint
clf.convert_to_treelite_model().to_treelite_checkpoint(checkpoint_path)
/opt/conda/envs/rapids/lib/python3.9/site-packages/cuml/internals/api_decorators.py:771: UserWarning: For reproducible results in Random Forest Classifier or for almost reproducible results in Random Forest Regressor, n_streams=1 is recommended. If n_streams is > 1, results may vary due to stream/thread timing differences, even when random_state is set
return func(**kwargs)
Copy the generated checkpoint file
checkpoint.tl
to another machine on which you’d like to run predictions.On the target machine, install Treelite by running
pip install treelite
orconda install -c conda-forge treelite
. The machine does not need to have an NVIDIA GPUs and does not need to have cuML installed.You can now load the model from the checkpoint, by running the following on the target machine:
[15]:
import treelite
# The checkpoint file has been copied over
checkpoint_path = './checkpoint.tl'
tl_model = treelite.Model.deserialize(checkpoint_path)
out_prob = treelite.gtil.predict(tl_model, X, pred_margin=True)
print(out_prob)
[[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[1. 0. 0. ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.8317397 0.16826029]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.16169165 0.83830833]
[0. 0.9941856 0.0058144 ]
[0. 0.8317397 0.16826029]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.8317397 0.16826029]
[0. 0.5163647 0.48363543]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.3457792 0.65422076]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9941856 0.0058144 ]
[0. 0.9841856 0.0158144 ]
[0. 0.9941856 0.0058144 ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.02447553 0.9755244 ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.62521124 0.37478876]
[0. 0.02447553 0.9755244 ]
[0. 0.02447553 0.9755244 ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.04102564 0.95897436]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.02447553 0.9755244 ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.600339 0.399661 ]
[0. 0. 1. ]
[0. 0.10388279 0.8961172 ]
[0. 0. 1. ]
[0. 0.12835832 0.87164164]
[0. 0. 1. ]
[0. 0.02447553 0.9755244 ]
[0. 0.16169165 0.83830833]
[0. 0.12835832 0.87164164]
[0. 0. 1. ]
[0. 0.3457792 0.65422076]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.3457792 0.65422076]
[0. 0.3457792 0.65422076]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.02447553 0.9755244 ]
[0. 0.16169165 0.83830833]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.04102564 0.95897436]
[0. 0. 1. ]
[0. 0. 1. ]
[0. 0.02447553 0.9755244 ]]